diff options
1071 files changed, 24878 insertions, 10812 deletions
diff --git a/Android.bp b/Android.bp index 4e7a7b4d7ae2..cd0720dd2065 100644 --- a/Android.bp +++ b/Android.bp @@ -151,6 +151,7 @@ java_defaults { "core/java/android/content/pm/dex/IArtManager.aidl", "core/java/android/content/pm/dex/ISnapshotRuntimeProfileCallback.aidl", "core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl", + "core/java/android/content/rollback/IRollbackManager.aidl", "core/java/android/database/IContentObserver.aidl", "core/java/android/debug/IAdbManager.aidl", "core/java/android/debug/IAdbTransport.aidl", @@ -461,11 +462,13 @@ java_defaults { "media/java/android/media/IAudioRoutesObserver.aidl", "media/java/android/media/IAudioService.aidl", "media/java/android/media/IAudioServerStateDispatcher.aidl", + "media/java/android/media/IMediaController2.aidl", "media/java/android/media/IMediaHTTPConnection.aidl", "media/java/android/media/IMediaHTTPService.aidl", "media/java/android/media/IMediaResourceMonitor.aidl", "media/java/android/media/IMediaRouterClient.aidl", "media/java/android/media/IMediaRouterService.aidl", + "media/java/android/media/IMediaSession2.aidl", "media/java/android/media/IMediaScannerListener.aidl", "media/java/android/media/IMediaScannerService.aidl", "media/java/android/media/IPlaybackConfigDispatcher.aidl", @@ -631,6 +634,7 @@ java_defaults { "wifi/java/android/net/wifi/rtt/IRttCallback.aidl", "wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl", "wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl", + "wifi/java/android/net/wifi/IDppCallback.aidl", "wifi/java/android/net/wifi/IWifiScanner.aidl", "packages/services/PacProcessor/com/android/net/IProxyService.aidl", "packages/services/Proxy/com/android/net/IProxyCallback.aidl", @@ -719,6 +723,7 @@ java_defaults { static_libs: [ "apex_aidl_interface-java", + "networkstack-aidl-interfaces-java", "framework-protos", "mediaplayer2-protos", "android.hidl.base-V1.0-java", @@ -861,6 +866,16 @@ 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/INetworkStackConnector.aidl", + ], + api_dir: "aidl/networkstack", +} + // Build ext.jar // ============================================================ java_library { diff --git a/api/current.txt b/api/current.txt index 328bd028bb2c..fad607ccefec 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3934,6 +3934,7 @@ package android.app { method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException; method public deprecated java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException; method public deprecated java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException; + method public boolean isActivityStartAllowedOnDisplay(android.content.Context, int, android.content.Intent); method public boolean isBackgroundRestricted(); method public deprecated boolean isInLockTaskMode(); method public boolean isLowRamDevice(); @@ -11302,6 +11303,7 @@ package android.content.pm { method public void updateSessionAppLabel(int, java.lang.CharSequence); field public static final java.lang.String ACTION_SESSION_COMMITTED = "android.content.pm.action.SESSION_COMMITTED"; field public static final java.lang.String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS"; + field public static final java.lang.String ACTION_SESSION_UPDATED = "android.content.pm.action.SESSION_UPDATED"; field public static final java.lang.String EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME"; field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME"; field public static final java.lang.String EXTRA_SESSION = "android.content.pm.extra.SESSION"; @@ -28447,6 +28449,7 @@ package android.net { method public android.net.ProxyInfo getHttpProxy(); method public java.lang.String getInterfaceName(); method public java.util.List<android.net.LinkAddress> getLinkAddresses(); + method public int getMtu(); method public java.lang.String getPrivateDnsServerName(); method public java.util.List<android.net.RouteInfo> getRoutes(); method public boolean isPrivateDnsActive(); @@ -29552,6 +29555,7 @@ package android.net.wifi { method public int getWifiState(); method public boolean is5GHzBandSupported(); method public boolean isDeviceToApRttSupported(); + method public boolean isDppSupported(); method public boolean isEnhancedPowerReportingSupported(); method public boolean isOweSupported(); method public boolean isP2pSupported(); @@ -29686,21 +29690,20 @@ package android.net.wifi { field public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR; } - public deprecated class WpsInfo implements android.os.Parcelable { - ctor public deprecated WpsInfo(); - ctor public deprecated WpsInfo(android.net.wifi.WpsInfo); - method public deprecated int describeContents(); - method public deprecated java.lang.String toString(); - method public deprecated void writeToParcel(android.os.Parcel, int); - field public deprecated java.lang.String BSSID; - field public static final deprecated android.os.Parcelable.Creator<android.net.wifi.WpsInfo> CREATOR; - field public static final deprecated int DISPLAY = 1; // 0x1 - field public static final deprecated int INVALID = 4; // 0x4 - field public static final deprecated int KEYPAD = 2; // 0x2 - field public static final deprecated int LABEL = 3; // 0x3 - field public static final deprecated int PBC = 0; // 0x0 - field public deprecated java.lang.String pin; - field public deprecated int setup; + public class WpsInfo implements android.os.Parcelable { + ctor public WpsInfo(); + ctor public WpsInfo(android.net.wifi.WpsInfo); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public java.lang.String BSSID; + field public static final android.os.Parcelable.Creator<android.net.wifi.WpsInfo> CREATOR; + field public static final int DISPLAY = 1; // 0x1 + field public static final int INVALID = 4; // 0x4 + field public static final int KEYPAD = 2; // 0x2 + field public static final int LABEL = 3; // 0x3 + field public static final int PBC = 0; // 0x0 + field public java.lang.String pin; + field public int setup; } } @@ -41937,13 +41940,13 @@ package android.system { method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException; method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException; method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException; - method public static void setegid(int) throws android.system.ErrnoException; + method public static deprecated void setegid(int) throws android.system.ErrnoException; method public static void setenv(java.lang.String, java.lang.String, boolean) throws android.system.ErrnoException; - method public static void seteuid(int) throws android.system.ErrnoException; - method public static void setgid(int) throws android.system.ErrnoException; + method public static deprecated void seteuid(int) throws android.system.ErrnoException; + method public static deprecated void setgid(int) throws android.system.ErrnoException; method public static int setsid() throws android.system.ErrnoException; method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException; - method public static void setuid(int) throws android.system.ErrnoException; + method public static deprecated void setuid(int) throws android.system.ErrnoException; method public static void setxattr(java.lang.String, java.lang.String, byte[], int) throws android.system.ErrnoException; method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException; method public static java.io.FileDescriptor socket(int, int, int) throws android.system.ErrnoException; @@ -42909,6 +42912,7 @@ package android.telecom { field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS"; field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER"; + field public static final java.lang.String EXTRA_SIP_INVITE = "android.telecom.extra.SIP_INVITE"; field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 32; // 0x20 field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10 field public static final int PROPERTY_IS_RTT = 256; // 0x100 @@ -51899,6 +51903,7 @@ package android.view.animation { public abstract class Animation implements java.lang.Cloneable { ctor public Animation(); ctor public Animation(android.content.Context, android.util.AttributeSet); + method public void addAnimationListener(android.view.animation.Animation.AnimationListener); method protected void applyTransformation(float, android.view.animation.Transformation); method public void cancel(); method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException; @@ -51923,6 +51928,7 @@ package android.view.animation { method public void initialize(int, int, int, int); method public boolean isFillEnabled(); method public boolean isInitialized(); + method public void removeAnimationListener(android.view.animation.Animation.AnimationListener); method public void reset(); method protected float resolveSize(int, float, int, int); method public void restrictDuration(long); diff --git a/api/system-current.txt b/api/system-current.txt index 5ccb7bb2e9ae..e27c29f657eb 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1221,7 +1221,6 @@ package android.content.pm { public abstract class PackageManager { method public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract boolean arePermissionsIndividuallyControlled(); - method public boolean canSuspendPackage(java.lang.String); method public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(java.lang.String); method public android.content.pm.ApplicationInfo getApplicationInfoAsUser(java.lang.String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method public android.content.pm.dex.ArtManager getArtManager(); @@ -1235,6 +1234,7 @@ package android.content.pm { method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String); method public abstract int getIntentVerificationStatusAsUser(java.lang.String, int); method public abstract int getPermissionFlags(java.lang.String, java.lang.String, android.os.UserHandle); + method public java.lang.String[] getUnsuspendablePackages(java.lang.String[]); method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle); method public abstract int installExistingPackage(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract int installExistingPackage(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException; @@ -3000,7 +3000,8 @@ package android.media { field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1 field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4 field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2 - field public static final int FLAG_FROM_KEY = 4096; // 0x1000 + field public static final int FLAG_FROM_KEY = 65536; // 0x10000 + field public static final int SUCCESS = 0; // 0x0 } public static abstract class AudioManager.AudioServerStateCallback { @@ -3117,8 +3118,10 @@ package android.media.audiopolicy { method public int detachMixes(java.util.List<android.media.audiopolicy.AudioMix>); method public int getFocusDuckingBehavior(); method public int getStatus(); + method public int removeUidDeviceAffinity(int); method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setRegistration(java.lang.String); + method public int setUidDeviceAffinity(int, java.util.List<android.media.AudioDeviceInfo>); method public java.lang.String toLogFriendlyString(); field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0 @@ -3160,6 +3163,34 @@ package android.media.audiopolicy { package android.media.session { + public final class ControllerCallbackLink implements android.os.Parcelable { + ctor public ControllerCallbackLink(android.media.session.ControllerCallbackLink.CallbackStub); + method public int describeContents(); + method public android.os.IBinder getBinder(); + method public void notifyEvent(java.lang.String, android.os.Bundle); + method public void notifyExtrasChanged(android.os.Bundle); + method public void notifyMetadataChanged(android.media.MediaMetadata); + method public void notifyPlaybackStateChanged(android.media.session.PlaybackState); + method public void notifyQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>); + method public void notifyQueueTitleChanged(java.lang.CharSequence); + method public void notifySessionDestroyed(); + method public void notifyVolumeInfoChanged(int, android.media.AudioAttributes, int, int, int); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.media.session.ControllerCallbackLink> CREATOR; + } + + public static abstract class ControllerCallbackLink.CallbackStub { + ctor public ControllerCallbackLink.CallbackStub(); + method public void onEvent(java.lang.String, android.os.Bundle); + method public void onExtrasChanged(android.os.Bundle); + method public void onMetadataChanged(android.media.MediaMetadata); + method public void onPlaybackStateChanged(android.media.session.PlaybackState); + method public void onQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>); + method public void onQueueTitleChanged(java.lang.CharSequence); + method public void onSessionDestroyed(); + method public void onVolumeInfoChanged(int, android.media.AudioAttributes, int, int, int); + } + public final class MediaSessionManager { method public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, android.os.Handler); method public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, android.os.Handler); @@ -3173,6 +3204,64 @@ package android.media.session { method public abstract void onVolumeKeyLongPress(android.view.KeyEvent); } + public final class SessionCallbackLink implements android.os.Parcelable { + ctor public SessionCallbackLink(android.media.session.SessionCallbackLink.CallbackStub); + method public int describeContents(); + method public android.os.IBinder getBinder(); + method public void notifyAdjustVolume(java.lang.String, int, int, android.media.session.ControllerCallbackLink, int); + method public void notifyCommand(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle, android.os.ResultReceiver); + method public void notifyCustomAction(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void notifyFastForward(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void notifyMediaButton(java.lang.String, int, int, android.content.Intent, int, android.os.ResultReceiver); + method public void notifyMediaButtonFromController(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.content.Intent); + method public void notifyNext(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void notifyPause(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void notifyPlay(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void notifyPlayFromMediaId(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void notifyPlayFromSearch(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void notifyPlayFromUri(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle); + method public void notifyPrepare(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void notifyPrepareFromMediaId(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void notifyPrepareFromSearch(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void notifyPrepareFromUri(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle); + method public void notifyPrevious(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void notifyRate(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.media.Rating); + method public void notifyRewind(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void notifySeekTo(java.lang.String, int, int, android.media.session.ControllerCallbackLink, long); + method public void notifySetVolumeTo(java.lang.String, int, int, android.media.session.ControllerCallbackLink, int); + method public void notifySkipToTrack(java.lang.String, int, int, android.media.session.ControllerCallbackLink, long); + method public void notifyStop(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.media.session.SessionCallbackLink> CREATOR; + } + + public static abstract class SessionCallbackLink.CallbackStub { + ctor public SessionCallbackLink.CallbackStub(); + method public void onAdjustVolume(java.lang.String, int, int, android.media.session.ControllerCallbackLink, int); + method public void onCommand(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle, android.os.ResultReceiver); + method public void onCustomAction(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void onFastForward(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void onMediaButton(java.lang.String, int, int, android.content.Intent, int, android.os.ResultReceiver); + method public void onMediaButtonFromController(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.content.Intent); + method public void onNext(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void onPause(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void onPlay(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void onPlayFromMediaId(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void onPlayFromSearch(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void onPlayFromUri(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle); + method public void onPrepare(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void onPrepareFromMediaId(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void onPrepareFromSearch(java.lang.String, int, int, android.media.session.ControllerCallbackLink, java.lang.String, android.os.Bundle); + method public void onPrepareFromUri(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle); + method public void onPrevious(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void onRate(java.lang.String, int, int, android.media.session.ControllerCallbackLink, android.media.Rating); + method public void onRewind(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + method public void onSeekTo(java.lang.String, int, int, android.media.session.ControllerCallbackLink, long); + method public void onSetVolumeTo(java.lang.String, int, int, android.media.session.ControllerCallbackLink, int); + method public void onSkipToTrack(java.lang.String, int, int, android.media.session.ControllerCallbackLink, long); + method public void onStop(java.lang.String, int, int, android.media.session.ControllerCallbackLink); + } + } package android.media.soundtrigger { @@ -3518,7 +3607,20 @@ package android.net { ctor public LinkAddress(java.lang.String); } + public final class LinkProperties implements android.os.Parcelable { + ctor public LinkProperties(); + method public boolean addRoute(android.net.RouteInfo); + method public void clear(); + method public void setDnsServers(java.util.Collection<java.net.InetAddress>); + method public void setDomains(java.lang.String); + method public void setHttpProxy(android.net.ProxyInfo); + method public void setInterfaceName(java.lang.String); + method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>); + method public void setMtu(int); + } + public final class NetworkCapabilities implements android.os.Parcelable { + method public int getSignalStrength(); field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16 } @@ -3538,6 +3640,10 @@ package android.net { method public abstract void onRequestScores(android.net.NetworkKey[]); } + public static class NetworkRequest.Builder { + method public android.net.NetworkRequest.Builder setSignalStrength(int); + } + public class NetworkScoreManager { method public boolean clearScores() throws java.lang.SecurityException; method public void disableScoring() throws java.lang.SecurityException; @@ -3612,6 +3718,26 @@ package android.net { package android.net.wifi { + public abstract class DppStatusCallback { + ctor public DppStatusCallback(); + method public abstract void onConfiguratorSuccess(int); + method public abstract void onEnrolleeSuccess(int); + method public abstract void onFailure(int); + method public abstract void onProgress(int); + field public static final int DPP_EVENT_FAILURE = -7; // 0xfffffff9 + field public static final int DPP_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe + field public static final int DPP_EVENT_FAILURE_BUSY = -5; // 0xfffffffb + field public static final int DPP_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc + field public static final int DPP_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7 + field public static final int DPP_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff + field public static final int DPP_EVENT_FAILURE_NOT_COMPATIBLE = -3; // 0xfffffffd + field public static final int DPP_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8 + field public static final int DPP_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa + field public static final int DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0 + field public static final int DPP_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1 + field public static final int DPP_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0 + } + public deprecated class RttManager { method public void disableResponder(android.net.wifi.RttManager.ResponderCallback); method public void enableResponder(android.net.wifi.RttManager.ResponderCallback); @@ -3841,7 +3967,10 @@ package android.net.wifi { method public void save(android.net.wifi.WifiConfiguration, android.net.wifi.WifiManager.ActionListener); method public void setDeviceMobilityState(int); method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration); + method public void startDppAsConfiguratorInitiator(java.lang.String, int, int, android.os.Handler, android.net.wifi.DppStatusCallback); + method public void startDppAsEnrolleeInitiator(java.lang.String, android.os.Handler, android.net.wifi.DppStatusCallback); method public boolean startScan(android.os.WorkSource); + method public void stopDppSession(); method public void unregisterNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback); field public static final int CHANGE_REASON_ADDED = 0; // 0x0 field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2 @@ -3851,6 +3980,8 @@ package android.net.wifi { field public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; // 0x2 field public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; // 0x3 field public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; // 0x0 + field public static final int DPP_NETWORK_ROLE_AP = 1; // 0x1 + field public static final int DPP_NETWORK_ROLE_STA = 0; // 0x0 field public static final java.lang.String EXTRA_CHANGE_REASON = "changeReason"; field public static final java.lang.String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges"; field public static final java.lang.String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; @@ -5139,10 +5270,12 @@ package android.service.contentcapture { method public final java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities(); method public final java.util.Set<java.lang.String> getContentCaptureDisabledPackages(); method public void onActivitySnapshot(android.view.contentcapture.ContentCaptureSessionId, android.service.contentcapture.SnapshotData); + method public void onConnected(); method public void onContentCaptureEvent(android.view.contentcapture.ContentCaptureSessionId, android.view.contentcapture.ContentCaptureEvent); method public deprecated void onContentCaptureEventsRequest(android.view.contentcapture.ContentCaptureSessionId, android.service.contentcapture.ContentCaptureEventsRequest); method public void onCreateContentCaptureSession(android.view.contentcapture.ContentCaptureContext, android.view.contentcapture.ContentCaptureSessionId); method public void onDestroyContentCaptureSession(android.view.contentcapture.ContentCaptureSessionId); + method public void onDisconnected(); method public final void setActivityContentCaptureEnabled(android.content.ComponentName, boolean); method public final void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>); method public final void setPackageContentCaptureEnabled(java.lang.String, boolean); @@ -6244,13 +6377,13 @@ package android.telephony { method public deprecated boolean getDataEnabled(int); method public boolean getEmergencyCallbackMode(); method public java.lang.String getIsimDomain(); - method public int getPreferredNetworkType(int); method public int getPreferredNetworkTypeBitmap(); method public int getRadioPowerState(); method public int getSimApplicationState(); method public int getSimCardState(); method public int getSupportedRadioAccessFamily(); method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms(); + method public android.telephony.UiccCardInfo[] getUiccCardsInfo(); method public android.telephony.UiccSlotInfo[] getUiccSlotsInfo(); method public android.os.Bundle getVisualVoicemailSettings(); method public int getVoiceActivationState(); @@ -6300,29 +6433,6 @@ package android.telephony { field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; field public static final int INVALID_CARD_ID = -1; // 0xffffffff field public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000L; // 0xea60L - field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4 - field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5 - field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6 - field public static final int NETWORK_MODE_GLOBAL = 7; // 0x7 - field public static final int NETWORK_MODE_GSM_ONLY = 1; // 0x1 - field public static final int NETWORK_MODE_GSM_UMTS = 3; // 0x3 - field public static final int NETWORK_MODE_LTE_CDMA_EVDO = 8; // 0x8 - field public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; // 0xa - field public static final int NETWORK_MODE_LTE_GSM_WCDMA = 9; // 0x9 - field public static final int NETWORK_MODE_LTE_ONLY = 11; // 0xb - field public static final int NETWORK_MODE_LTE_TDSCDMA = 15; // 0xf - field public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; // 0x16 - field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; // 0x11 - field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; // 0x14 - field public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; // 0x13 - field public static final int NETWORK_MODE_LTE_WCDMA = 12; // 0xc - field public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; // 0x15 - field public static final int NETWORK_MODE_TDSCDMA_GSM = 16; // 0x10 - field public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; // 0x12 - field public static final int NETWORK_MODE_TDSCDMA_ONLY = 13; // 0xd - field public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14; // 0xe - field public static final int NETWORK_MODE_WCDMA_ONLY = 2; // 0x2 - field public static final int NETWORK_MODE_WCDMA_PREF = 0; // 0x0 field public static final int NETWORK_TYPE_BITMASK_1xRTT = 128; // 0x80 field public static final int NETWORK_TYPE_BITMASK_CDMA = 16; // 0x10 field public static final int NETWORK_TYPE_BITMASK_EDGE = 4; // 0x4 @@ -6370,6 +6480,18 @@ package android.telephony { field public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR; } + public class UiccCardInfo implements android.os.Parcelable { + ctor public UiccCardInfo(boolean, int, java.lang.String, java.lang.String, int); + method public int describeContents(); + method public int getCardId(); + method public java.lang.String getEid(); + method public java.lang.String getIccId(); + method public int getSlotIndex(); + method public boolean isEuicc(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.UiccCardInfo> CREATOR; + } + public class UiccSlotInfo implements android.os.Parcelable { ctor public UiccSlotInfo(boolean, boolean, java.lang.String, int, int, boolean); method public int describeContents(); @@ -6692,6 +6814,7 @@ package android.telephony.ims { field public static final int DIALSTRING_SS_CONF = 1; // 0x1 field public static final int DIALSTRING_USSD = 2; // 0x2 field public static final java.lang.String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; + field public static final java.lang.String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS"; field public static final java.lang.String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; field public static final java.lang.String EXTRA_CHILD_NUMBER = "ChildNum"; field public static final java.lang.String EXTRA_CNA = "cna"; diff --git a/api/test-current.txt b/api/test-current.txt index 71a06f11b692..9c51c9fe84e0 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -72,6 +72,7 @@ package android.app { method public void resizeStack(int, android.graphics.Rect) throws java.lang.SecurityException; method public void resizeStack(int, android.graphics.Rect, boolean); method public void resizeTask(int, android.graphics.Rect); + method public void setDisplayToSingleTaskInstance(int); method public void setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException; method public void setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) throws java.lang.SecurityException; method public void startSystemLockTaskMode(int); @@ -329,6 +330,11 @@ package android.content { method public android.os.UserHandle getUser(); method public int getUserId(); method public void setAutofillCompatibilityEnabled(boolean); + field public static final java.lang.String ROLLBACK_SERVICE = "rollback"; + } + + public class Intent implements java.lang.Cloneable android.os.Parcelable { + field public static final java.lang.String ACTION_PACKAGE_ROLLBACK_EXECUTED = "android.intent.action.PACKAGE_ROLLBACK_EXECUTED"; } } @@ -351,6 +357,10 @@ package android.content.pm { ctor public LauncherApps(android.content.Context); } + public static class PackageInstaller.SessionParams implements android.os.Parcelable { + method public void setEnableRollback(); + } + public abstract class PackageManager { method public abstract boolean arePermissionsIndividuallyControlled(); method public abstract java.lang.String getDefaultBrowserPackageNameAsUser(int); @@ -398,6 +408,42 @@ package android.content.res { } +package android.content.rollback { + + public final class PackageRollbackInfo implements android.os.Parcelable { + ctor public PackageRollbackInfo(java.lang.String, android.content.rollback.PackageRollbackInfo.PackageVersion, android.content.rollback.PackageRollbackInfo.PackageVersion); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.content.rollback.PackageRollbackInfo> CREATOR; + field public final android.content.rollback.PackageRollbackInfo.PackageVersion higherVersion; + field public final android.content.rollback.PackageRollbackInfo.PackageVersion lowerVersion; + field public final java.lang.String packageName; + } + + public static class PackageRollbackInfo.PackageVersion { + ctor public PackageRollbackInfo.PackageVersion(long); + field public final long versionCode; + } + + public final class RollbackInfo implements android.os.Parcelable { + ctor public RollbackInfo(android.content.rollback.PackageRollbackInfo); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.content.rollback.RollbackInfo> CREATOR; + field public final android.content.rollback.PackageRollbackInfo targetPackage; + } + + public final class RollbackManager { + method public void executeRollback(android.content.rollback.RollbackInfo, android.content.IntentSender); + method public void expireRollbackForPackage(java.lang.String); + method public android.content.rollback.RollbackInfo getAvailableRollback(java.lang.String); + method public java.util.List<java.lang.String> getPackagesWithAvailableRollbacks(); + method public java.util.List<android.content.rollback.RollbackInfo> getRecentlyExecutedRollbacks(); + method public void reloadPersistedData(); + } + +} + package android.database.sqlite { public class SQLiteCompatibilityWalFlags { @@ -1108,6 +1154,20 @@ package android.service.autofill { method public void apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int) throws java.lang.Exception; } + public final class CompositeUserData implements android.os.Parcelable { + ctor public CompositeUserData(android.service.autofill.UserData, android.service.autofill.UserData); + method public int describeContents(); + method public java.lang.String[] getCategoryIds(); + method public android.os.Bundle getDefaultFieldClassificationArgs(); + method public java.lang.String getFieldClassificationAlgorithm(); + method public java.lang.String getFieldClassificationAlgorithmForCategory(java.lang.String); + method public android.util.ArrayMap<java.lang.String, java.lang.String> getFieldClassificationAlgorithms(); + method public android.util.ArrayMap<java.lang.String, android.os.Bundle> getFieldClassificationArgs(); + method public java.lang.String[] getValues(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.autofill.CompositeUserData> CREATOR; + } + public final class CustomDescription implements android.os.Parcelable { method public android.util.SparseArray<android.service.autofill.InternalOnClickAction> getActions(); } diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h index 498eebce5999..04d4f9a6fd06 100644 --- a/cmds/bootanimation/BootAnimation.h +++ b/cmds/bootanimation/BootAnimation.h @@ -114,7 +114,7 @@ public: virtual void shutdown() {} }; - BootAnimation(sp<Callbacks> callbacks); + explicit BootAnimation(sp<Callbacks> callbacks); sp<SurfaceComposerClient> session() const; @@ -128,7 +128,7 @@ private: class TimeCheckThread : public Thread { public: - TimeCheckThread(BootAnimation* bootAnimation); + explicit TimeCheckThread(BootAnimation* bootAnimation); virtual ~TimeCheckThread(); private: virtual status_t readyToRun(); diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index fe7099b2f3ea..abe18ba8a415 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -23,6 +23,7 @@ cc_defaults { ], tidy_flags: [ "-system-headers", + "-warnings-as-errors=*", ], } diff --git a/cmds/idmap2/idmap2/Main.cpp b/cmds/idmap2/idmap2/Main.cpp index 4012555235a8..445fac52f997 100644 --- a/cmds/idmap2/idmap2/Main.cpp +++ b/cmds/idmap2/idmap2/Main.cpp @@ -29,8 +29,8 @@ using android::idmap2::CommandLineOptions; -typedef std::map<std::string, std::function<bool(const std::vector<std::string>&, std::ostream&)>> - NameToFunctionMap; +using NameToFunctionMap = + std::map<std::string, std::function<bool(const std::vector<std::string>&, std::ostream&)>>; namespace { diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index ef560d1ee710..49187475ccdb 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -56,8 +56,7 @@ std::unique_ptr<std::vector<std::string>> FindApkFiles(const std::vector<std::st } paths.insert(apk_paths->cbegin(), apk_paths->cend()); } - return std::unique_ptr<std::vector<std::string>>( - new std::vector<std::string>(paths.cbegin(), paths.cend())); + return std::make_unique<std::vector<std::string>>(paths.cbegin(), paths.cend()); } } // namespace @@ -138,15 +137,15 @@ bool Scan(const std::vector<std::string>& args, std::ostream& out_error) { } std::stringstream stream; - for (auto iter = interesting_apks.cbegin(); iter != interesting_apks.cend(); ++iter) { - const std::string idmap_path = Idmap::CanonicalIdmapPathFor(output_directory, *iter); + for (const auto& apk : interesting_apks) { + const std::string idmap_path = Idmap::CanonicalIdmapPathFor(output_directory, apk); std::stringstream dev_null; if (!Verify(std::vector<std::string>({"--idmap-path", idmap_path}), dev_null) && !Create(std::vector<std::string>({ "--target-apk-path", target_apk_path, "--overlay-apk-path", - *iter, + apk, "--idmap-path", idmap_path, }), diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 7b16093434fb..d2e46e15fc59 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -56,8 +56,7 @@ Status error(const std::string& msg) { } // namespace -namespace android { -namespace os { +namespace android::os { Status Idmap2Service::getIdmapPath(const std::string& overlay_apk_path, int32_t user_id ATTRIBUTE_UNUSED, std::string* _aidl_return) { @@ -132,9 +131,8 @@ Status Idmap2Service::createIdmap(const std::string& target_apk_path, return error("failed to write to idmap path " + idmap_path); } - _aidl_return->reset(new std::string(idmap_path)); + *_aidl_return = std::make_unique<std::string>(idmap_path); return ok(); } -} // namespace os -} // namespace android +} // namespace android::os diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h index 4e5abc9069f4..e0bc22e9e9e6 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.h +++ b/cmds/idmap2/idmap2d/Idmap2Service.h @@ -25,8 +25,8 @@ #include "android/os/BnIdmap2.h" -namespace android { -namespace os { +namespace android::os { + class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 { public: static char const* getServiceName() { @@ -46,7 +46,7 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 { const std::string& overlay_apk_path, int32_t user_id, std::unique_ptr<std::string>* _aidl_return); }; -} // namespace os -} // namespace android + +} // namespace android::os #endif // IDMAP2_IDMAP2D_IDMAP2SERVICE_H_ diff --git a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h index 2368aeadbc9f..2c3e9d321881 100644 --- a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h +++ b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h @@ -23,8 +23,7 @@ #include "idmap2/Idmap.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { class BinaryStreamVisitor : public Visitor { public: @@ -43,7 +42,6 @@ class BinaryStreamVisitor : public Visitor { std::ostream& stream_; }; -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 #endif // IDMAP2_INCLUDE_IDMAP2_BINARYSTREAMVISITOR_H_ diff --git a/cmds/idmap2/include/idmap2/CommandLineOptions.h b/cmds/idmap2/include/idmap2/CommandLineOptions.h index f3aa68b8d1a2..b93e71631d08 100644 --- a/cmds/idmap2/include/idmap2/CommandLineOptions.h +++ b/cmds/idmap2/include/idmap2/CommandLineOptions.h @@ -23,8 +23,7 @@ #include <string> #include <vector> -namespace android { -namespace idmap2 { +namespace android::idmap2 { /* * Utility class to convert a command line, including options (--path foo.txt), @@ -65,7 +64,6 @@ class CommandLineOptions { std::string name_; }; -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 #endif // IDMAP2_INCLUDE_IDMAP2_COMMANDLINEOPTIONS_H_ diff --git a/cmds/idmap2/include/idmap2/FileUtils.h b/cmds/idmap2/include/idmap2/FileUtils.h index 84cc69a95ac5..5c41c49906cd 100644 --- a/cmds/idmap2/include/idmap2/FileUtils.h +++ b/cmds/idmap2/include/idmap2/FileUtils.h @@ -22,9 +22,7 @@ #include <string> #include <vector> -namespace android { -namespace idmap2 { -namespace utils { +namespace android::idmap2::utils { constexpr const mode_t kIdmapFilePermissionMask = 0133; // u=rw,g=r,o=r @@ -37,8 +35,6 @@ std::unique_ptr<std::string> ReadFile(int fd); std::unique_ptr<std::string> ReadFile(const std::string& path); -} // namespace utils -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2::utils #endif // IDMAP2_INCLUDE_IDMAP2_FILEUTILS_H_ diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index 837b7c5264d5..b989e4c3f9d1 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -57,8 +57,7 @@ #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { class Idmap; class Visitor; @@ -271,7 +270,6 @@ class Visitor { virtual void visit(const IdmapData::TypeEntry& type_entry) = 0; }; -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 #endif // IDMAP2_INCLUDE_IDMAP2_IDMAP_H_ diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h index d106f19af998..323796b05986 100644 --- a/cmds/idmap2/include/idmap2/ResourceUtils.h +++ b/cmds/idmap2/include/idmap2/ResourceUtils.h @@ -25,14 +25,10 @@ #include "idmap2/Idmap.h" #include "idmap2/Result.h" -namespace android { -namespace idmap2 { -namespace utils { +namespace android::idmap2::utils { Result<std::string> WARN_UNUSED ResToTypeEntryName(const AssetManager2& am, ResourceId resid); -} // namespace utils -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2::utils #endif // IDMAP2_INCLUDE_IDMAP2_RESOURCEUTILS_H_ diff --git a/cmds/idmap2/include/idmap2/Xml.h b/cmds/idmap2/include/idmap2/Xml.h index 9ab5ec454750..dd89dee0f64f 100644 --- a/cmds/idmap2/include/idmap2/Xml.h +++ b/cmds/idmap2/include/idmap2/Xml.h @@ -25,8 +25,7 @@ #include "androidfw/ResourceTypes.h" #include "utils/String16.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { class Xml { public: @@ -45,7 +44,6 @@ class Xml { DISALLOW_COPY_AND_ASSIGN(Xml); }; -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 #endif // IDMAP2_INCLUDE_IDMAP2_XML_H_ diff --git a/cmds/idmap2/include/idmap2/ZipFile.h b/cmds/idmap2/include/idmap2/ZipFile.h index 9edbbe0cce90..8f50e36256f6 100644 --- a/cmds/idmap2/include/idmap2/ZipFile.h +++ b/cmds/idmap2/include/idmap2/ZipFile.h @@ -21,11 +21,10 @@ #include <string> #include "android-base/macros.h" -#include "ziparchive/zip_archive.h" #include "idmap2/Result.h" +#include "ziparchive/zip_archive.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { struct MemoryChunk { size_t size; @@ -56,7 +55,6 @@ class ZipFile { DISALLOW_COPY_AND_ASSIGN(ZipFile); }; -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 #endif // IDMAP2_INCLUDE_IDMAP2_ZIPFILE_H_ diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp index b7765bc3d836..96513283ac51 100644 --- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp +++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp @@ -22,8 +22,7 @@ #include "idmap2/BinaryStreamVisitor.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { void BinaryStreamVisitor::Write16(uint16_t value) { uint16_t x = htodl(value); @@ -77,5 +76,4 @@ void BinaryStreamVisitor::visit(const IdmapData::TypeEntry& type_entry) { } } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/CommandLineOptions.cpp b/cmds/idmap2/libidmap2/CommandLineOptions.cpp index 28c3797226e1..cabc8f398c46 100644 --- a/cmds/idmap2/libidmap2/CommandLineOptions.cpp +++ b/cmds/idmap2/libidmap2/CommandLineOptions.cpp @@ -26,13 +26,11 @@ #include "idmap2/CommandLineOptions.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { std::unique_ptr<std::vector<std::string>> CommandLineOptions::ConvertArgvToVector( int argc, const char** argv) { - return std::unique_ptr<std::vector<std::string>>( - new std::vector<std::string>(argv + 1, argv + argc)); + return std::make_unique<std::vector<std::string>>(argv + 1, argv + argc); } CommandLineOptions& CommandLineOptions::OptionalFlag(const std::string& name, @@ -111,8 +109,8 @@ bool CommandLineOptions::Parse(const std::vector<std::string>& argv, std::ostrea } if (!mandatory_opts.empty()) { - for (auto iter = mandatory_opts.cbegin(); iter != mandatory_opts.cend(); ++iter) { - outError << "error: " << *iter << ": missing mandatory option" << std::endl; + for (const auto& opt : mandatory_opts) { + outError << "error: " << opt << ": missing mandatory option" << std::endl; } Usage(outError); return false; @@ -159,5 +157,4 @@ void CommandLineOptions::Usage(std::ostream& out) const { } } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/FileUtils.cpp b/cmds/idmap2/libidmap2/FileUtils.cpp index 88d40d1f523d..0255727fc8c6 100644 --- a/cmds/idmap2/libidmap2/FileUtils.cpp +++ b/cmds/idmap2/libidmap2/FileUtils.cpp @@ -15,10 +15,10 @@ */ #include <dirent.h> -#include <errno.h> #include <sys/types.h> #include <unistd.h> +#include <cerrno> #include <fstream> #include <memory> #include <string> @@ -27,9 +27,7 @@ #include "idmap2/FileUtils.h" -namespace android { -namespace idmap2 { -namespace utils { +namespace android::idmap2::utils { std::unique_ptr<std::vector<std::string>> FindFiles(const std::string& root, bool recurse, const FindFilesPredicate& predicate) { @@ -79,6 +77,4 @@ std::unique_ptr<std::string> ReadFile(int fd) { return r == 0 ? std::move(str) : nullptr; } -} // namespace utils -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2::utils diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 5822745a95c3..37d6af8fa477 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -36,8 +36,7 @@ #include "idmap2/Result.h" #include "idmap2/ZipFile.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { namespace { @@ -450,5 +449,4 @@ void Idmap::accept(Visitor* v) const { } } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp index b36df24a0da7..fc9677994fc0 100644 --- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp @@ -24,8 +24,7 @@ #include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { #define RESID(pkg, type, entry) (((pkg) << 24) | ((type) << 16) | (entry)) @@ -73,5 +72,4 @@ void PrettyPrintVisitor::visit(const IdmapData::TypeEntry& type_entry) { } } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp index a6bf5fb6e687..ec2decf782e2 100644 --- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp @@ -27,8 +27,7 @@ using android::ApkAssets; -namespace android { -namespace idmap2 { +namespace android::idmap2 { // verbatim copy fomr PrettyPrintVisitor.cpp, move to common utils #define RESID(pkg, type, entry) (((pkg) << 24) | ((type) << 16) | (entry)) @@ -127,5 +126,4 @@ void RawPrintVisitor::print(const std::string& value, const char* fmt, ...) { offset_ += kIdmapStringLength; } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp index 5c897832e9d5..04e0ec756045 100644 --- a/cmds/idmap2/libidmap2/ResourceUtils.cpp +++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp @@ -25,9 +25,7 @@ using android::StringPiece16; using android::util::Utf16ToUtf8; -namespace android { -namespace idmap2 { -namespace utils { +namespace android::idmap2::utils { Result<std::string> WARN_UNUSED ResToTypeEntryName(const AssetManager2& am, ResourceId resid) { AssetManager2::ResourceName name; @@ -49,6 +47,4 @@ Result<std::string> WARN_UNUSED ResToTypeEntryName(const AssetManager2& am, Reso return {out}; } -} // namespace utils -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2::utils diff --git a/cmds/idmap2/libidmap2/Xml.cpp b/cmds/idmap2/libidmap2/Xml.cpp index 5543722ce4fe..0075a922d676 100644 --- a/cmds/idmap2/libidmap2/Xml.cpp +++ b/cmds/idmap2/libidmap2/Xml.cpp @@ -21,8 +21,7 @@ #include "idmap2/Xml.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { std::unique_ptr<const Xml> Xml::Create(const uint8_t* data, size_t size, bool copyData) { std::unique_ptr<Xml> xml(new Xml()); @@ -78,5 +77,4 @@ Xml::~Xml() { xml_.uninit(); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/libidmap2/ZipFile.cpp b/cmds/idmap2/libidmap2/ZipFile.cpp index 9fb611dd8e8d..15ec3f9d3afe 100644 --- a/cmds/idmap2/libidmap2/ZipFile.cpp +++ b/cmds/idmap2/libidmap2/ZipFile.cpp @@ -20,8 +20,7 @@ #include "idmap2/Result.h" #include "idmap2/ZipFile.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { std::unique_ptr<MemoryChunk> MemoryChunk::Allocate(size_t size) { void* ptr = ::operator new(sizeof(MemoryChunk) + size); @@ -63,5 +62,4 @@ Result<uint32_t> ZipFile::Crc(const std::string& entryPath) const { return status == 0 ? Result<uint32_t>(entry.crc32) : kResultError; } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp index 3b9dbe97e894..2698ac0a734d 100644 --- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp +++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp @@ -31,8 +31,7 @@ using ::testing::NotNull; -namespace android { -namespace idmap2 { +namespace android::idmap2 { TEST(BinaryStreamVisitorTests, CreateBinaryStreamViaBinaryStreamVisitor) { std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len); @@ -124,5 +123,4 @@ TEST(BinaryStreamVisitorTests, CreateIdmapFromApkAssetsInteropWithLoadedIdmap) { ASSERT_FALSE(success); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/CommandLineOptionsTests.cpp b/cmds/idmap2/tests/CommandLineOptionsTests.cpp index 243d23a0f2db..c27d27a16b94 100644 --- a/cmds/idmap2/tests/CommandLineOptionsTests.cpp +++ b/cmds/idmap2/tests/CommandLineOptionsTests.cpp @@ -38,8 +38,7 @@ #include "TestHelpers.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { TEST(CommandLineOptionsTests, Flag) { bool foo = true; @@ -193,5 +192,4 @@ TEST(CommandLineOptionsTests, Usage) { std::string::npos); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp index 6584ee32a509..4bf832a34691 100644 --- a/cmds/idmap2/tests/FileUtilsTests.cpp +++ b/cmds/idmap2/tests/FileUtilsTests.cpp @@ -29,9 +29,7 @@ using ::testing::NotNull; -namespace android { -namespace idmap2 { -namespace utils { +namespace android::idmap2::utils { TEST(FileUtilsTests, FindFilesFindEverythingNonRecursive) { const auto& root = GetTestDataPath(); @@ -71,6 +69,4 @@ TEST(FileUtilsTests, ReadFile) { close(pipefd[0]); } -} // namespace utils -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2::utils diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp index 255f3c102b85..22f48e9a396f 100644 --- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp +++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp @@ -46,8 +46,7 @@ using ::android::util::ExecuteBinary; using ::testing::NotNull; -namespace android { -namespace idmap2 { +namespace android::idmap2 { class Idmap2BinaryTests : public Idmap2Tests {}; @@ -313,5 +312,4 @@ TEST_F(Idmap2BinaryTests, InvalidCommandLineOptions) { ASSERT_NE(result->status, EXIT_SUCCESS); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index dc80e0e145ac..963f22ec8d72 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -37,8 +37,7 @@ using ::testing::IsNull; using ::testing::NotNull; -namespace android { -namespace idmap2 { +namespace android::idmap2 { TEST(IdmapTests, TestCanonicalIdmapPathFor) { ASSERT_EQ(Idmap::CanonicalIdmapPathFor("/foo", "/vendor/overlay/bar.apk"), @@ -346,23 +345,23 @@ class TestVisitor : public Visitor { explicit TestVisitor(std::ostream& stream) : stream_(stream) { } - void visit(const Idmap& idmap ATTRIBUTE_UNUSED) { + void visit(const Idmap& idmap ATTRIBUTE_UNUSED) override { stream_ << "TestVisitor::visit(Idmap)" << std::endl; } - void visit(const IdmapHeader& idmap ATTRIBUTE_UNUSED) { + void visit(const IdmapHeader& idmap ATTRIBUTE_UNUSED) override { stream_ << "TestVisitor::visit(IdmapHeader)" << std::endl; } - void visit(const IdmapData& idmap ATTRIBUTE_UNUSED) { + void visit(const IdmapData& idmap ATTRIBUTE_UNUSED) override { stream_ << "TestVisitor::visit(IdmapData)" << std::endl; } - void visit(const IdmapData::Header& idmap ATTRIBUTE_UNUSED) { + void visit(const IdmapData::Header& idmap ATTRIBUTE_UNUSED) override { stream_ << "TestVisitor::visit(IdmapData::Header)" << std::endl; } - void visit(const IdmapData::TypeEntry& idmap ATTRIBUTE_UNUSED) { + void visit(const IdmapData::TypeEntry& idmap ATTRIBUTE_UNUSED) override { stream_ << "TestVisitor::visit(IdmapData::TypeEntry)" << std::endl; } @@ -391,5 +390,4 @@ TEST(IdmapTests, TestVisitor) { "TestVisitor::visit(IdmapData::TypeEntry)\n"); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/Main.cpp b/cmds/idmap2/tests/Main.cpp index 0f683ffd8eef..2b13fed8d60d 100644 --- a/cmds/idmap2/tests/Main.cpp +++ b/cmds/idmap2/tests/Main.cpp @@ -22,15 +22,13 @@ #include "TestHelpers.h" -namespace android { -namespace idmap2 { +namespace android::idmap2 { std::string GetTestDataPath() { return base::GetExecutableDirectory() + "/tests/data"; } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp index 0c4f493e9f6c..7736bc063131 100644 --- a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp @@ -33,8 +33,7 @@ using ::testing::NotNull; using android::ApkAssets; -namespace android { -namespace idmap2 { +namespace android::idmap2 { TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitor) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); @@ -78,5 +77,4 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitorWithoutAccessToApks) { ASSERT_NE(stream.str().find("0x7f020000 -> 0x7f020000\n"), std::string::npos); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index 6285f217b21e..0318cd20a9bb 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -29,8 +29,7 @@ using ::testing::NotNull; -namespace android { -namespace idmap2 { +namespace android::idmap2 { TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); @@ -79,5 +78,4 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { ASSERT_NE(stream.str().find("0000021c: 00000000 0x7f020000 -> 0x7f020000\n"), std::string::npos); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/ResourceUtilsTests.cpp b/cmds/idmap2/tests/ResourceUtilsTests.cpp index c8578d3b340a..ad78685646b4 100644 --- a/cmds/idmap2/tests/ResourceUtilsTests.cpp +++ b/cmds/idmap2/tests/ResourceUtilsTests.cpp @@ -28,8 +28,7 @@ using ::testing::NotNull; -namespace android { -namespace idmap2 { +namespace android::idmap2 { class ResourceUtilsTests : public Idmap2Tests { protected: @@ -62,5 +61,4 @@ TEST_F(ResourceUtilsTests, ResToTypeEntryNameNoSuchResourceId) { ASSERT_FALSE(name); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h index 356db7af1385..45525a5b7657 100644 --- a/cmds/idmap2/tests/TestHelpers.h +++ b/cmds/idmap2/tests/TestHelpers.h @@ -19,8 +19,7 @@ #include <string> -namespace android { -namespace idmap2 { +namespace android::idmap2 { const unsigned char idmap_raw_data[] = { // IDMAP HEADER @@ -162,7 +161,6 @@ class Idmap2Tests : public testing::Test { std::string idmap_path_; }; -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 #endif // IDMAP2_TESTS_TESTHELPERS_H_ diff --git a/cmds/idmap2/tests/XmlTests.cpp b/cmds/idmap2/tests/XmlTests.cpp index 40758b42e1ff..fe79d8f2c5a9 100644 --- a/cmds/idmap2/tests/XmlTests.cpp +++ b/cmds/idmap2/tests/XmlTests.cpp @@ -27,8 +27,7 @@ using ::testing::IsNull; using ::testing::NotNull; -namespace android { -namespace idmap2 { +namespace android::idmap2 { TEST(XmlTests, Create) { auto zip = ZipFile::Open(GetTestDataPath() + "/target/target.apk"); @@ -68,5 +67,4 @@ TEST(XmlTests, FindTag) { ASSERT_THAT(fail, IsNull()); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/idmap2/tests/ZipFileTests.cpp b/cmds/idmap2/tests/ZipFileTests.cpp index 6e4a501a51ac..79be43ce0e42 100644 --- a/cmds/idmap2/tests/ZipFileTests.cpp +++ b/cmds/idmap2/tests/ZipFileTests.cpp @@ -28,8 +28,7 @@ using ::testing::IsNull; using ::testing::NotNull; -namespace android { -namespace idmap2 { +namespace android::idmap2 { TEST(ZipFileTests, BasicOpen) { auto zip = ZipFile::Open(GetTestDataPath() + "/target/target.apk"); @@ -66,5 +65,4 @@ TEST(ZipFileTests, Uncompress) { ASSERT_THAT(fail, IsNull()); } -} // namespace idmap2 -} // namespace android +} // namespace android::idmap2 diff --git a/cmds/incident_helper/src/TextParserBase.h b/cmds/incident_helper/src/TextParserBase.h index 784c181d9741..a6074e71c035 100644 --- a/cmds/incident_helper/src/TextParserBase.h +++ b/cmds/incident_helper/src/TextParserBase.h @@ -30,7 +30,7 @@ class TextParserBase { public: String8 name; - TextParserBase(String8 name) : name(name) {}; + explicit TextParserBase(String8 name) : name(name) {}; virtual ~TextParserBase() {}; virtual status_t Parse(const int in, const int out) const = 0; diff --git a/cmds/incident_helper/src/ih_util.h b/cmds/incident_helper/src/ih_util.h index c02a3493724a..09dc8e6fdbfc 100644 --- a/cmds/incident_helper/src/ih_util.h +++ b/cmds/incident_helper/src/ih_util.h @@ -109,7 +109,7 @@ double toDouble(const std::string& s); class Reader { public: - Reader(const int fd); + explicit Reader(const int fd); ~Reader(); bool readLine(std::string* line); @@ -162,7 +162,7 @@ private: class Message { public: - Message(Table* table); + explicit Message(Table* table); ~Message(); // Reconstructs the typical proto message by adding its message fields. diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h index 6252ad295224..c63a183b70b9 100644 --- a/cmds/incidentd/src/IncidentService.h +++ b/cmds/incidentd/src/IncidentService.h @@ -97,7 +97,7 @@ private: // ================================================================================ class IncidentService : public BnIncidentManager { public: - IncidentService(const sp<Looper>& handlerLooper); + explicit IncidentService(const sp<Looper>& handlerLooper); virtual ~IncidentService(); virtual Status reportIncident(const IncidentReportArgs& args); diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h index a3df4903de45..a0159d9a8649 100644 --- a/cmds/incidentd/src/Privacy.h +++ b/cmds/incidentd/src/Privacy.h @@ -83,7 +83,7 @@ public: static PrivacySpec new_spec(int dest); private: - PrivacySpec(uint8_t dest) : dest(dest) {} + explicit PrivacySpec(uint8_t dest) : dest(dest) {} }; } // namespace incidentd diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h index 45fd9443e9d0..2a3abd7b4d97 100644 --- a/cmds/incidentd/src/Reporter.h +++ b/cmds/incidentd/src/Reporter.h @@ -89,7 +89,7 @@ public: ReportRequestSet batch; Reporter(); // PROD must use this constructor. - Reporter(const char* directory); // For testing purpose only. + explicit Reporter(const char* directory); // For testing purpose only. virtual ~Reporter(); // Run the report as described in the batch and args parameters. diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp index 10d226822331..32ec1ba90cda 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -415,7 +415,7 @@ struct WorkerThreadData : public virtual RefBase { bool workerDone; status_t workerError; - WorkerThreadData(const WorkerThreadSection* section); + explicit WorkerThreadData(const WorkerThreadSection* section); virtual ~WorkerThreadData(); }; diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java index c6d2bc891b18..ded20c4b38bf 100644 --- a/cmds/media/src/com/android/commands/media/Media.java +++ b/cmds/media/src/com/android/commands/media/Media.java @@ -19,12 +19,12 @@ package com.android.commands.media; import android.app.ActivityManager; import android.content.Context; -import android.content.pm.ParceledListSlice; +import android.media.AudioAttributes; import android.media.MediaMetadata; +import android.media.session.ControllerCallbackLink; import android.media.session.ISessionController; -import android.media.session.ISessionControllerCallback; import android.media.session.ISessionManager; -import android.media.session.ParcelableVolumeInfo; +import android.media.session.MediaSession.QueueItem; import android.media.session.PlaybackState; import android.os.Bundle; import android.os.HandlerThread; @@ -178,13 +178,7 @@ public class Media extends BaseCommand { KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD)); } - class ControllerMonitor extends ISessionControllerCallback.Stub { - private final ISessionController mController; - - public ControllerMonitor(ISessionController controller) { - mController = controller; - } - + class ControllerCallbackStub extends ControllerCallbackLink.CallbackStub { @Override public void onSessionDestroyed() { System.out.println("onSessionDestroyed. Enter q to quit."); @@ -208,24 +202,37 @@ public class Media extends BaseCommand { } @Override - public void onQueueChanged(ParceledListSlice queue) throws RemoteException { + public void onQueueChanged(List<QueueItem> queue) { System.out.println("onQueueChanged, " - + (queue == null ? "null queue" : " size=" + queue.getList().size())); + + (queue == null ? "null queue" : " size=" + queue.size())); } @Override - public void onQueueTitleChanged(CharSequence title) throws RemoteException { + public void onQueueTitleChanged(CharSequence title) { System.out.println("onQueueTitleChange " + title); } @Override - public void onExtrasChanged(Bundle extras) throws RemoteException { + public void onExtrasChanged(Bundle extras) { System.out.println("onExtrasChanged " + extras); } @Override - public void onVolumeInfoChanged(ParcelableVolumeInfo info) throws RemoteException { - System.out.println("onVolumeInfoChanged " + info); + public void onVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType, + int maxVolume, int currentVolume) { + System.out.println("onVolumeInfoChanged " + "volumeType=" + volumeType + ", attrs=" + + attrs + ", controlType=" + controlType + ", maxVolume=" + maxVolume + + ", currentVolume=" + currentVolume); + } + } + + private class ControllerMonitor { + private final ISessionController mController; + private final ControllerCallbackLink mControllerCallbackLink; + + ControllerMonitor(ISessionController controller) { + mController = controller; + mControllerCallbackLink = new ControllerCallbackLink(new ControllerCallbackStub()); } void printUsageMessage() { @@ -244,7 +251,7 @@ public class Media extends BaseCommand { @Override protected void onLooperPrepared() { try { - mController.registerCallbackListener(PACKAGE_NAME, ControllerMonitor.this); + mController.registerCallbackListener(PACKAGE_NAME, mControllerCallbackLink); } catch (RemoteException e) { System.out.println("Error registering monitor callback"); } @@ -287,7 +294,7 @@ public class Media extends BaseCommand { } finally { cbThread.getLooper().quit(); try { - mController.unregisterCallbackListener(this); + mController.unregisterCallbackListener(mControllerCallbackLink); } catch (Exception e) { // ignoring } diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 0114ff488413..f0b751db5ae9 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -216,6 +216,7 @@ cc_test { "tests/anomaly/AnomalyTracker_test.cpp", "tests/ConfigManager_test.cpp", "tests/external/puller_util_test.cpp", + "tests/external/StatsPuller_test.cpp", "tests/indexed_priority_queue_test.cpp", "tests/LogEntryMatcher_test.cpp", "tests/LogEvent_test.cpp", diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index 50b64b986866..f2a46636c382 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -704,7 +704,7 @@ status_t StatsService::cmd_log_app_breadcrumb(int out, const Vector<String8>& ar status_t StatsService::cmd_print_pulled_metrics(int out, const Vector<String8>& args) { int s = atoi(args[1].c_str()); vector<shared_ptr<LogEvent> > stats; - if (mPullerManager->Pull(s, getElapsedRealtimeNs(), &stats)) { + if (mPullerManager->Pull(s, &stats)) { for (const auto& it : stats) { dprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str()); } diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h index 3badb1faece6..bca858e67f13 100644 --- a/cmds/statsd/src/anomaly/AlarmMonitor.h +++ b/cmds/statsd/src/anomaly/AlarmMonitor.h @@ -42,7 +42,7 @@ namespace statsd { * Timestamps are in seconds since epoch in a uint32, so will fail in year 2106. */ struct InternalAlarm : public RefBase { - InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) { + explicit InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) { } const uint32_t timestampSec; diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index fd62843701b2..e5415430d82a 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -927,7 +927,7 @@ message WifiLockStateChanged { * Logs wifi signal strength changes. * * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java + * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java */ message WifiSignalStrengthChanged { // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto. @@ -938,7 +938,7 @@ message WifiSignalStrengthChanged { * Logs wifi scans performed by an app. * * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java + * frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java */ message WifiScanStateChanged { repeated AttributionNode attribution_node = 1; @@ -954,7 +954,7 @@ message WifiScanStateChanged { * Logs wifi multicast locks held by an app * * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java + * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMulticastLockManager.java */ message WifiMulticastLockStateChanged { repeated AttributionNode attribution_node = 1; @@ -964,6 +964,8 @@ message WifiMulticastLockStateChanged { ON = 1; } optional State state = 2; + + optional string tag = 3; } /** @@ -3474,10 +3476,10 @@ message BuildInformation { * Pulls on-device BatteryStats power use calculations for the overall device. */ message DeviceCalculatedPowerUse { - // Power used by the device in mAh, as computed by BatteryStats, since BatteryStats last reset - // (i.e. roughly since device was last significantly charged). - // Currently, this is BatteryStatsHelper.getComputedPower() (not getTotalPower()). - optional float computed_power_milli_amp_hours = 1; + // Power used by the device in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since + // BatteryStats last reset (i.e. roughly since device was last significantly charged). + // Currently, this is from BatteryStatsHelper.getComputedPower() (not getTotalPower()). + optional int64 computed_power_nano_amp_secs = 1; } /** @@ -3489,9 +3491,9 @@ message DeviceCalculatedPowerBlameUid { // Uid being blamed. Note: isolated uids have already been mapped to host uid. optional int32 uid = 1 [(is_uid) = true]; - // Power used by this uid in mAh, as computed by BatteryStats, since BatteryStats last reset - // (i.e. roughly since device was last significantly charged). - optional float power_milli_amp_hours = 2; + // Power used by this uid in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since + // BatteryStats last reset (i.e. roughly since device was last significantly charged). + optional int64 power_nano_amp_secs = 2; } /** @@ -3525,9 +3527,9 @@ message DeviceCalculatedPowerBlameOther { } optional DrainType drain_type = 1; - // Power used by this item in mAh, as computed by BatteryStats, since BatteryStats last reset - // (i.e. roughly since device was last significantly charged). - optional float power_milli_amp_hours = 2; + // Power used by this item in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since + // BatteryStats last reset (i.e. roughly since device was last significantly charged). + optional int64 power_nano_amp_secs = 2; } /** diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h index a6f88af4b4d6..2c8814772839 100644 --- a/cmds/statsd/src/condition/ConditionWizard.h +++ b/cmds/statsd/src/condition/ConditionWizard.h @@ -29,7 +29,7 @@ namespace statsd { class ConditionWizard : public virtual android::RefBase { public: ConditionWizard(){}; // for testing - ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers) + explicit ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers) : mAllConditions(conditionTrackers){}; virtual ~ConditionWizard(){}; diff --git a/cmds/statsd/src/config/ConfigKey.h b/cmds/statsd/src/config/ConfigKey.h index dc79519d1f34..4cc9393fbd02 100644 --- a/cmds/statsd/src/config/ConfigKey.h +++ b/cmds/statsd/src/config/ConfigKey.h @@ -33,7 +33,7 @@ using std::string; class ConfigKey { public: ConfigKey(); - explicit ConfigKey(const ConfigKey& that); + ConfigKey(const ConfigKey& that); ConfigKey(int uid, const int64_t& id); ~ConfigKey(); diff --git a/cmds/statsd/src/external/PowerStatsPuller.h b/cmds/statsd/src/external/PowerStatsPuller.h index dd5ff8fe08d0..6f15bd68fa94 100644 --- a/cmds/statsd/src/external/PowerStatsPuller.h +++ b/cmds/statsd/src/external/PowerStatsPuller.h @@ -28,6 +28,8 @@ namespace statsd { class PowerStatsPuller : public StatsPuller { public: PowerStatsPuller(); + +private: bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; }; diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.h b/cmds/statsd/src/external/ResourceHealthManagerPuller.h index 9b238eaf5f83..f650fccc447e 100644 --- a/cmds/statsd/src/external/ResourceHealthManagerPuller.h +++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.h @@ -28,7 +28,9 @@ namespace statsd { */ class ResourceHealthManagerPuller : public StatsPuller { public: - ResourceHealthManagerPuller(int tagId); + explicit ResourceHealthManagerPuller(int tagId); + +private: bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; }; diff --git a/cmds/statsd/src/external/ResourceThermalManagerPuller.h b/cmds/statsd/src/external/ResourceThermalManagerPuller.h index 13c675aad680..531379226bb0 100644 --- a/cmds/statsd/src/external/ResourceThermalManagerPuller.h +++ b/cmds/statsd/src/external/ResourceThermalManagerPuller.h @@ -29,6 +29,8 @@ namespace statsd { class ResourceThermalManagerPuller : public StatsPuller { public: ResourceThermalManagerPuller(); + +private: bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; }; diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.h b/cmds/statsd/src/external/StatsCompanionServicePuller.h index 0a49732fe120..2e133207f01d 100644 --- a/cmds/statsd/src/external/StatsCompanionServicePuller.h +++ b/cmds/statsd/src/external/StatsCompanionServicePuller.h @@ -25,14 +25,14 @@ namespace statsd { class StatsCompanionServicePuller : public StatsPuller { public: - StatsCompanionServicePuller(int tagId); - bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override; + explicit StatsCompanionServicePuller(int tagId); void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) override; private: Mutex mStatsCompanionServiceLock; sp<IStatsCompanionService> mStatsCompanionService = nullptr; + bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override; }; } // namespace statsd diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp index 7043d663eb2c..c7c22ee85f0f 100644 --- a/cmds/statsd/src/external/StatsPuller.cpp +++ b/cmds/statsd/src/external/StatsPuller.cpp @@ -34,48 +34,52 @@ void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; } StatsPuller::StatsPuller(const int tagId) : mTagId(tagId) { - // Pullers can cause significant impact to system health and battery. - // So that we don't pull too frequently. - mCoolDownNs = StatsPullerManager::kAllPullAtomInfo.find(tagId)->second.coolDownNs; - VLOG("Puller for tag %d created. Cooldown set to %lld", mTagId, (long long)mCoolDownNs); } -bool StatsPuller::Pull(const int64_t elapsedTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) { +bool StatsPuller::Pull(std::vector<std::shared_ptr<LogEvent>>* data) { lock_guard<std::mutex> lock(mLock); - int64_t wallClockTimeNs = getWallClockNs(); + int64_t elapsedTimeNs = getElapsedRealtimeNs(); StatsdStats::getInstance().notePull(mTagId); - if (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs) { - (*data) = mCachedData; - StatsdStats::getInstance().notePullFromCache(mTagId); - StatsdStats::getInstance().notePullDelay(mTagId, getElapsedRealtimeNs() - elapsedTimeNs); - return true; + const bool shouldUseCache = elapsedTimeNs - mLastPullTimeNs < + StatsPullerManager::kAllPullAtomInfo.at(mTagId).coolDownNs; + if (shouldUseCache) { + if (mHasGoodData) { + (*data) = mCachedData; + StatsdStats::getInstance().notePullFromCache(mTagId); + } + return mHasGoodData; } - if (mMinPullIntervalNs > elapsedTimeNs - mLastPullTimeNs) { - mMinPullIntervalNs = elapsedTimeNs - mLastPullTimeNs; - StatsdStats::getInstance().updateMinPullIntervalSec(mTagId, - mMinPullIntervalNs / NS_PER_SEC); + + if (mLastPullTimeNs > 0) { + StatsdStats::getInstance().updateMinPullIntervalSec( + mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC); } mCachedData.clear(); mLastPullTimeNs = elapsedTimeNs; - int64_t pullStartTimeNs = getElapsedRealtimeNs(); - bool ret = PullInternal(&mCachedData); - if (!ret) { - mCachedData.clear(); - return false; + mHasGoodData = PullInternal(&mCachedData); + if (!mHasGoodData) { + return mHasGoodData; } - StatsdStats::getInstance().notePullTime(mTagId, getElapsedRealtimeNs() - pullStartTimeNs); - for (const shared_ptr<LogEvent>& data : mCachedData) { - data->setElapsedTimestampNs(elapsedTimeNs); - data->setLogdWallClockTimestampNs(wallClockTimeNs); + const int64_t pullDurationNs = getElapsedRealtimeNs() - elapsedTimeNs; + StatsdStats::getInstance().notePullTime(mTagId, pullDurationNs); + const bool pullTimeOut = + pullDurationNs > StatsPullerManager::kAllPullAtomInfo.at(mTagId).pullTimeoutNs; + if (pullTimeOut) { + // Something went wrong. Discard the data. + clearCacheLocked(); + mHasGoodData = false; + StatsdStats::getInstance().notePullTimeout(mTagId); + ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId, + (long long)pullDurationNs); + return mHasGoodData; } if (mCachedData.size() > 0) { mapAndMergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId); - (*data) = mCachedData; } - StatsdStats::getInstance().notePullDelay(mTagId, getElapsedRealtimeNs() - elapsedTimeNs); - return ret; + (*data) = mCachedData; + return mHasGoodData; } int StatsPuller::ForceClearCache() { @@ -84,6 +88,10 @@ int StatsPuller::ForceClearCache() { int StatsPuller::clearCache() { lock_guard<std::mutex> lock(mLock); + return clearCacheLocked(); +} + +int StatsPuller::clearCacheLocked() { int ret = mCachedData.size(); mCachedData.clear(); mLastPullTimeNs = 0; @@ -91,7 +99,8 @@ int StatsPuller::clearCache() { } int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) { - if (timestampNs - mLastPullTimeNs > mCoolDownNs) { + if (timestampNs - mLastPullTimeNs > + StatsPullerManager::kAllPullAtomInfo.at(mTagId).coolDownNs) { return clearCache(); } else { return 0; diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h index cafd7979601a..c83c4f8536ae 100644 --- a/cmds/statsd/src/external/StatsPuller.h +++ b/cmds/statsd/src/external/StatsPuller.h @@ -18,7 +18,6 @@ #include <android/os/IStatsCompanionService.h> #include <utils/RefBase.h> -#include <utils/String16.h> #include <mutex> #include <vector> #include "packages/UidMap.h" @@ -33,14 +32,20 @@ namespace statsd { class StatsPuller : public virtual RefBase { public: - StatsPuller(const int tagId); + explicit StatsPuller(const int tagId); virtual ~StatsPuller() {} - // Pulls the data. The returned data will have elapsedTimeNs set as timeNs - // and will have wallClockTimeNs set as current wall clock time. - // Return true if the pull is successful. - bool Pull(const int64_t timeNs, std::vector<std::shared_ptr<LogEvent>>* data); + // Pulls the most recent data. + // The data may be served from cache if consecutive pulls come within + // predefined cooldown time. + // Returns true if the pull was successful. + // Returns false when + // 1) the pull fails + // 2) pull takes longer than mPullTimeoutNs (intrinsic to puller) + // If a metric wants to make any change to the data, like timestamps, it + // should make a copy as this data may be shared with multiple metrics. + bool Pull(std::vector<std::shared_ptr<LogEvent>>* data); // Clear cache immediately int ForceClearCache(); @@ -53,29 +58,30 @@ public: virtual void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService){}; protected: - // The atom tag id this puller pulls const int mTagId; private: mutable std::mutex mLock; - // Minimum time before this puller does actual pull again. - // If a pull request comes before cooldown, a cached version from purevious pull - // will be returned. - // The actual value should be determined by individual pullers. - int64_t mCoolDownNs; - // For puller stats - int64_t mMinPullIntervalNs = LONG_MAX; + // Real puller impl. virtual bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) = 0; + bool mHasGoodData = false; + + int64_t mLastPullTimeNs; + // Cache of data from last pull. If next request comes before cool down finishes, // cached data will be returned. + // Cached data is cleared when + // 1) A pull fails + // 2) A new pull request comes after cooldown time. + // 3) clearCache is called. std::vector<std::shared_ptr<LogEvent>> mCachedData; - int64_t mLastPullTimeNs; - int clearCache(); + int clearCacheLocked(); + static sp<UidMap> mUidMap; }; diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index c070ca375d74..4a716cf3fa77 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -53,195 +53,172 @@ const int64_t NO_ALARM_UPDATE = INT64_MAX; const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { // wifi_bytes_transfer {android::util::WIFI_BYTES_TRANSFER, - {{2, 3, 4, 5}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER)}}, + {.additiveFields = {2, 3, 4, 5}, + .puller = new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER)}}, // wifi_bytes_transfer_by_fg_bg {android::util::WIFI_BYTES_TRANSFER_BY_FG_BG, - {{3, 4, 5, 6}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER_BY_FG_BG)}}, + {.additiveFields = {3, 4, 5, 6}, + .puller = new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER_BY_FG_BG)}}, // mobile_bytes_transfer {android::util::MOBILE_BYTES_TRANSFER, - {{2, 3, 4, 5}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER)}}, + {.additiveFields = {2, 3, 4, 5}, + .puller = new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER)}}, // mobile_bytes_transfer_by_fg_bg {android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG, - {{3, 4, 5, 6}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG)}}, + {.additiveFields = {3, 4, 5, 6}, + .puller = + new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG)}}, // bluetooth_bytes_transfer {android::util::BLUETOOTH_BYTES_TRANSFER, - {{2, 3}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::BLUETOOTH_BYTES_TRANSFER)}}, + {.additiveFields = {2, 3}, + .puller = new StatsCompanionServicePuller(android::util::BLUETOOTH_BYTES_TRANSFER)}}, // kernel_wakelock {android::util::KERNEL_WAKELOCK, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}}, + {.puller = new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}}, // subsystem_sleep_state - {android::util::SUBSYSTEM_SLEEP_STATE, - {{}, 1 * NS_PER_SEC, new SubsystemSleepStatePuller()}}, + {android::util::SUBSYSTEM_SLEEP_STATE, {.puller = new SubsystemSleepStatePuller()}}, // on_device_power_measurement - {android::util::ON_DEVICE_POWER_MEASUREMENT, {{}, 1 * NS_PER_SEC, new PowerStatsPuller()}}, + {android::util::ON_DEVICE_POWER_MEASUREMENT, {.puller = new PowerStatsPuller()}}, // cpu_time_per_freq {android::util::CPU_TIME_PER_FREQ, - {{3}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_FREQ)}}, + {.additiveFields = {3}, + .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_FREQ)}}, // cpu_time_per_uid {android::util::CPU_TIME_PER_UID, - {{2, 3}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID)}}, + {.additiveFields = {2, 3}, + .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID)}}, // cpu_time_per_uid_freq // the throttling is 3sec, handled in // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader {android::util::CPU_TIME_PER_UID_FREQ, - {{4}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID_FREQ)}}, + {.additiveFields = {4}, + .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID_FREQ)}}, // cpu_active_time // the throttling is 3sec, handled in // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader {android::util::CPU_ACTIVE_TIME, - {{2}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CPU_ACTIVE_TIME)}}, + {.additiveFields = {2}, + .puller = new StatsCompanionServicePuller(android::util::CPU_ACTIVE_TIME)}}, // cpu_cluster_time // the throttling is 3sec, handled in // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader {android::util::CPU_CLUSTER_TIME, - {{3}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CPU_CLUSTER_TIME)}}, + {.additiveFields = {3}, + .puller = new StatsCompanionServicePuller(android::util::CPU_CLUSTER_TIME)}}, // wifi_activity_energy_info {android::util::WIFI_ACTIVITY_INFO, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::WIFI_ACTIVITY_INFO)}}, + {.puller = new StatsCompanionServicePuller(android::util::WIFI_ACTIVITY_INFO)}}, // modem_activity_info {android::util::MODEM_ACTIVITY_INFO, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::MODEM_ACTIVITY_INFO)}}, + {.puller = new StatsCompanionServicePuller(android::util::MODEM_ACTIVITY_INFO)}}, // bluetooth_activity_info {android::util::BLUETOOTH_ACTIVITY_INFO, - {{}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::BLUETOOTH_ACTIVITY_INFO)}}, + {.puller = new StatsCompanionServicePuller(android::util::BLUETOOTH_ACTIVITY_INFO)}}, // system_elapsed_realtime {android::util::SYSTEM_ELAPSED_REALTIME, - {{}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME)}}, + {.pullTimeoutNs = NS_PER_SEC / 2, + .coolDownNs = NS_PER_SEC, + .puller = new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME)}}, // system_uptime {android::util::SYSTEM_UPTIME, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}}, + {.puller = new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}}, // remaining_battery_capacity {android::util::REMAINING_BATTERY_CAPACITY, - {{}, - 1 * NS_PER_SEC, - new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}}, + {.puller = new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}}, // full_battery_capacity {android::util::FULL_BATTERY_CAPACITY, - {{}, - 1 * NS_PER_SEC, - new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}}, + {.puller = new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}}, // battery_voltage {android::util::BATTERY_VOLTAGE, - {{}, 1 * NS_PER_SEC, new ResourceHealthManagerPuller(android::util::BATTERY_VOLTAGE)}}, - // battery_level + {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_VOLTAGE)}}, + // battery_voltage {android::util::BATTERY_LEVEL, - {{}, 1 * NS_PER_SEC, new ResourceHealthManagerPuller(android::util::BATTERY_LEVEL)}}, + {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_LEVEL)}}, // process_memory_state {android::util::PROCESS_MEMORY_STATE, - {{4, 5, 6, 7, 8, 9}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, + {.additiveFields = {4, 5, 6, 7, 8, 9}, + .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, // native_process_memory_state {android::util::NATIVE_PROCESS_MEMORY_STATE, - {{3, 4, 5, 6}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, + {.additiveFields = {3, 4, 5, 6}, + .puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, {android::util::PROCESS_MEMORY_HIGH_WATER_MARK, - {{3}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}}, + {.additiveFields = {3}, + .puller = + new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}}, // temperature - {android::util::TEMPERATURE, {{}, 1 * NS_PER_SEC, new ResourceThermalManagerPuller()}}, + {android::util::TEMPERATURE, {.puller = new ResourceThermalManagerPuller()}}, // binder_calls {android::util::BINDER_CALLS, - {{4, 5, 6, 8, 12}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::BINDER_CALLS)}}, + {.additiveFields = {4, 5, 6, 8, 12}, + .puller = new StatsCompanionServicePuller(android::util::BINDER_CALLS)}}, // binder_calls_exceptions {android::util::BINDER_CALLS_EXCEPTIONS, - {{}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::BINDER_CALLS_EXCEPTIONS)}}, + {.puller = new StatsCompanionServicePuller(android::util::BINDER_CALLS_EXCEPTIONS)}}, // looper_stats {android::util::LOOPER_STATS, - {{5, 6, 7, 8, 9}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::LOOPER_STATS)}}, + {.additiveFields = {5, 6, 7, 8, 9}, + .puller = new StatsCompanionServicePuller(android::util::LOOPER_STATS)}}, // Disk Stats {android::util::DISK_STATS, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DISK_STATS)}}, + {.puller = new StatsCompanionServicePuller(android::util::DISK_STATS)}}, // Directory usage {android::util::DIRECTORY_USAGE, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}}, + {.puller = new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}}, // Size of app's code, data, and cache {android::util::APP_SIZE, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::APP_SIZE)}}, + {.puller = new StatsCompanionServicePuller(android::util::APP_SIZE)}}, // Size of specific categories of files. Eg. Music. {android::util::CATEGORY_SIZE, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}}, + {.puller = new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}}, // Number of fingerprints registered to each user. {android::util::NUM_FINGERPRINTS, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS)}}, + {.puller = new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS)}}, // ProcStats. {android::util::PROC_STATS, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::PROC_STATS)}}, + {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS)}}, // ProcStatsPkgProc. {android::util::PROC_STATS_PKG_PROC, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::PROC_STATS_PKG_PROC)}}, + {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS_PKG_PROC)}}, // Disk I/O stats per uid. {android::util::DISK_IO, - {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, - 3 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::DISK_IO)}}, + {.additiveFields = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, + .coolDownNs = 3 * NS_PER_SEC, + .puller = new StatsCompanionServicePuller(android::util::DISK_IO)}}, // PowerProfile constants for power model calculations. {android::util::POWER_PROFILE, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::POWER_PROFILE)}}, + {.puller = new StatsCompanionServicePuller(android::util::POWER_PROFILE)}}, // Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses. {android::util::PROCESS_CPU_TIME, - {{} /* additive fields */, - 5 * NS_PER_SEC /* min cool-down in seconds*/, - new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}}, + {.coolDownNs = 5 * NS_PER_SEC /* min cool-down in seconds*/, + .puller = new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}}, {android::util::CPU_TIME_PER_THREAD_FREQ, - {{7, 9, 11, 13, 15, 17, 19, 21}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::CPU_TIME_PER_THREAD_FREQ)}}, + {.additiveFields = {7, 9, 11, 13, 15, 17, 19, 21}, + .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_THREAD_FREQ)}}, // DeviceCalculatedPowerUse. {android::util::DEVICE_CALCULATED_POWER_USE, - {{}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::DEVICE_CALCULATED_POWER_USE)}}, + {.puller = new StatsCompanionServicePuller(android::util::DEVICE_CALCULATED_POWER_USE)}}, // DeviceCalculatedPowerBlameUid. {android::util::DEVICE_CALCULATED_POWER_BLAME_UID, - {{}, // BatteryStats already merged isolated with host ids so it's unnecessary here. - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::DEVICE_CALCULATED_POWER_BLAME_UID)}}, + {.puller = new StatsCompanionServicePuller( + android::util::DEVICE_CALCULATED_POWER_BLAME_UID)}}, // DeviceCalculatedPowerBlameOther. {android::util::DEVICE_CALCULATED_POWER_BLAME_OTHER, - {{}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::DEVICE_CALCULATED_POWER_BLAME_OTHER)}}, + {.puller = new StatsCompanionServicePuller( + android::util::DEVICE_CALCULATED_POWER_BLAME_OTHER)}}, // BuildInformation. {android::util::BUILD_INFORMATION, - {{}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::BUILD_INFORMATION)}}, + {.puller = new StatsCompanionServicePuller(android::util::BUILD_INFORMATION)}}, }; StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) { } -bool StatsPullerManager::Pull(const int tagId, const int64_t timeNs, - vector<shared_ptr<LogEvent>>* data) { +bool StatsPullerManager::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) { VLOG("Initiating pulling %d", tagId); if (kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end()) { - bool ret = kAllPullAtomInfo.find(tagId)->second.puller->Pull(timeNs, data); + bool ret = kAllPullAtomInfo.find(tagId)->second.puller->Pull(data); VLOG("pulled %d items", (int)data->size()); return ret; } else { @@ -333,8 +310,9 @@ void StatsPullerManager::UnRegisterReceiver(int tagId, wp<PullDataReceiver> rece } } -void StatsPullerManager::OnAlarmFired(const int64_t currentTimeNs) { +void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) { AutoMutex _l(mLock); + int64_t wallClockNs = getWallClockNs(); int64_t minNextPullTimeNs = NO_ALARM_UPDATE; @@ -344,7 +322,7 @@ void StatsPullerManager::OnAlarmFired(const int64_t currentTimeNs) { vector<ReceiverInfo*> receivers = vector<ReceiverInfo*>(); if (pair.second.size() != 0) { for (ReceiverInfo& receiverInfo : pair.second) { - if (receiverInfo.nextPullTimeNs <= currentTimeNs) { + if (receiverInfo.nextPullTimeNs <= elapsedTimeNs) { receivers.push_back(&receiverInfo); } else { if (receiverInfo.nextPullTimeNs < minNextPullTimeNs) { @@ -360,22 +338,38 @@ void StatsPullerManager::OnAlarmFired(const int64_t currentTimeNs) { for (const auto& pullInfo : needToPull) { vector<shared_ptr<LogEvent>> data; - if (Pull(pullInfo.first, currentTimeNs, &data)) { - for (const auto& receiverInfo : pullInfo.second) { - sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote(); - if (receiverPtr != nullptr) { - receiverPtr->onDataPulled(data); - // we may have just come out of a coma, compute next pull time - receiverInfo->nextPullTimeNs = - (currentTimeNs - receiverInfo->nextPullTimeNs) / - receiverInfo->intervalNs * receiverInfo->intervalNs + - receiverInfo->intervalNs + receiverInfo->nextPullTimeNs; - if (receiverInfo->nextPullTimeNs < minNextPullTimeNs) { - minNextPullTimeNs = receiverInfo->nextPullTimeNs; - } - } else { - VLOG("receiver already gone."); + if (!Pull(pullInfo.first, &data)) { + VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs); + continue; + } + StatsdStats::getInstance().notePullDelay(pullInfo.first, + getElapsedRealtimeNs() - elapsedTimeNs); + + // Convention is to mark pull atom timestamp at request time. + // If we pull at t0, puller starts at t1, finishes at t2, and send back + // at t3, we mark t0 as its timestamp, which should correspond to its + // triggering event, such as condition change at t0. + // Here the triggering event is alarm fired from AlarmManager. + // In ValueMetricProducer and GaugeMetricProducer we do same thing + // when pull on condition change, etc. + for (auto& event : data) { + event->setElapsedTimestampNs(elapsedTimeNs); + event->setLogdWallClockTimestampNs(wallClockNs); + } + + for (const auto& receiverInfo : pullInfo.second) { + sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote(); + if (receiverPtr != nullptr) { + receiverPtr->onDataPulled(data); + // we may have just come out of a coma, compute next pull time + int numBucketsAhead = + (elapsedTimeNs - receiverInfo->nextPullTimeNs) / receiverInfo->intervalNs; + receiverInfo->nextPullTimeNs += (numBucketsAhead + 1) * receiverInfo->intervalNs; + if (receiverInfo->nextPullTimeNs < minNextPullTimeNs) { + minNextPullTimeNs = receiverInfo->nextPullTimeNs; } + } else { + VLOG("receiver already gone."); } } } diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h index 335073613a4a..807e4af03dae 100644 --- a/cmds/statsd/src/external/StatsPullerManager.h +++ b/cmds/statsd/src/external/StatsPullerManager.h @@ -26,6 +26,7 @@ #include <vector> #include "PullDataReceiver.h" #include "StatsPuller.h" +#include "guardrail/StatsdStats.h" #include "logd/LogEvent.h" namespace android { @@ -36,11 +37,19 @@ typedef struct { // The field numbers of the fields that need to be summed when merging // isolated uid with host uid. std::vector<int> additiveFields; - // How long should the puller wait before doing an actual pull again. Default - // 1 sec. Set this to 0 if this is handled elsewhere. + // Minimum time before this puller does actual pull again. + // Pullers can cause significant impact to system health and battery. + // So that we don't pull too frequently. + // If a pull request comes before cooldown, a cached version from previous pull + // will be returned. int64_t coolDownNs = 1 * NS_PER_SEC; // The actual puller sp<StatsPuller> puller; + // Max time allowed to pull this atom. + // We cannot reliably kill a pull thread. So we don't terminate the puller. + // The data is discarded if the pull takes longer than this and mHasGoodData + // marked as false. + int64_t pullTimeoutNs = StatsdStats::kPullMaxDelayNs; } PullAtomInfo; class StatsPullerManager : public virtual RefBase { @@ -61,13 +70,18 @@ public: // Verify if we know how to pull for this matcher bool PullerForMatcherExists(int tagId) const; - void OnAlarmFired(const int64_t timeNs); - - // Use respective puller to pull the data. The returned data will have - // elapsedTimeNs set as timeNs and will have wallClockTimeNs set as current - // wall clock time. - virtual bool Pull(const int tagId, const int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data); + void OnAlarmFired(int64_t elapsedTimeNs); + + // Pulls the most recent data. + // The data may be served from cache if consecutive pulls come within + // mCoolDownNs. + // Returns true if the pull was successful. + // Returns false when + // 1) the pull fails + // 2) pull takes longer than mPullTimeoutNs (intrinsic to puller) + // If the metric wants to make any change to the data, like timestamps, they + // should make a copy as this data may be shared with multiple metrics. + virtual bool Pull(int tagId, vector<std::shared_ptr<LogEvent>>* data); // Clear pull data cache immediately. int ForceClearPullerCache(); diff --git a/cmds/statsd/src/external/SubsystemSleepStatePuller.h b/cmds/statsd/src/external/SubsystemSleepStatePuller.h index 17ce5b4cb918..87f5f02614a9 100644 --- a/cmds/statsd/src/external/SubsystemSleepStatePuller.h +++ b/cmds/statsd/src/external/SubsystemSleepStatePuller.h @@ -29,6 +29,8 @@ namespace statsd { class SubsystemSleepStatePuller : public StatsPuller { public: SubsystemSleepStatePuller(); + +private: bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; }; diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index 3e5e82f7f4df..f4d0144e8878 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -373,6 +373,16 @@ void StatsdStats::notePullDataError(int pullAtomId) { mPulledAtomStats[pullAtomId].dataError++; } +void StatsdStats::notePullTimeout(int pullAtomId) { + lock_guard<std::mutex> lock(mLock); + mPulledAtomStats[pullAtomId].pullTimeout++; +} + +void StatsdStats::notePullExceedMaxDelay(int pullAtomId) { + lock_guard<std::mutex> lock(mLock); + mPulledAtomStats[pullAtomId].pullExceedMaxDelay++; +} + void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) { lock_guard<std::mutex> lock(mLock); @@ -429,6 +439,8 @@ void StatsdStats::resetInternalLocked() { pullStats.second.maxPullDelayNs = 0; pullStats.second.numPullDelay = 0; pullStats.second.dataError = 0; + pullStats.second.pullTimeout = 0; + pullStats.second.pullExceedMaxDelay = 0; } } @@ -535,13 +547,16 @@ void StatsdStats::dumpStats(int out) const { dprintf(out, "********Pulled Atom stats***********\n"); for (const auto& pair : mPulledAtomStats) { dprintf(out, - "Atom %d->(total pull)%ld, (pull from cache)%ld, (min pull interval)%ld, (average " - "pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay nanos)%lld, " - "(max pull delay nanos)%lld, (data error)%ld\n", + "Atom %d->(total pull)%ld, (pull from cache)%ld, (min pull interval)%ld \n" + " (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay " + "nanos)%lld, " + " (max pull delay nanos)%lld, (data error)%ld\n" + " (pull timeout)%ld, (pull exceed max delay)%ld\n", (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache, (long)pair.second.minPullIntervalSec, (long long)pair.second.avgPullTimeNs, (long long)pair.second.maxPullTimeNs, (long long)pair.second.avgPullDelayNs, - (long long)pair.second.maxPullDelayNs, pair.second.dataError); + (long long)pair.second.maxPullDelayNs, pair.second.dataError, + pair.second.pullTimeout, pair.second.pullExceedMaxDelay); } if (mAnomalyAlarmRegisteredStats > 0) { diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 31570379b080..dc647f888b6f 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -144,6 +144,8 @@ public: // How long to try to clear puller cache from last time static const long kPullerCacheClearIntervalSec = 1; + // Max time to do a pull. + static const int64_t kPullMaxDelayNs = 10 * NS_PER_SEC; /** * Report a new config has been received and report the static stats about the config. * @@ -296,6 +298,16 @@ public: void notePullDelay(int pullAtomId, int64_t pullDelayNs); /* + * Records pull exceeds timeout for the puller. + */ + void notePullTimeout(int pullAtomId); + + /* + * Records pull exceeds max delay for a metric. + */ + void notePullExceedMaxDelay(int pullAtomId); + + /* * Records when system server restarts. */ void noteSystemServerRestart(int32_t timeSec); @@ -335,6 +347,8 @@ public: int64_t maxPullDelayNs = 0; long numPullDelay = 0; long dataError = 0; + long pullTimeout = 0; + long pullExceedMaxDelay = 0; } PulledAtomStats; private: diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 8d61aba432d4..2ff8aa1793ec 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -41,6 +41,14 @@ LogEvent::LogEvent(log_msg& msg) { } } +LogEvent::LogEvent(const LogEvent& event) { + mTagId = event.mTagId; + mLogUid = event.mLogUid; + mElapsedTimestampNs = event.mElapsedTimestampNs; + mLogdTimestampNs = event.mLogdTimestampNs; + mValues = event.mValues; +} + LogEvent::LogEvent(const StatsLogEventWrapper& statsLogEventWrapper, int workChainIndex) { mTagId = statsLogEventWrapper.getTagId(); mLogdTimestampNs = statsLogEventWrapper.getWallClockTimeNs(); diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 5408d17b02b2..43e6e4f72da9 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -207,12 +207,15 @@ public: return &mValues; } + inline LogEvent makeCopy() { + return LogEvent(*this); + } + private: /** - * Don't copy, it's slower. If we really need this we can add it but let's try to - * avoid it. + * Only use this if copy is absolutely needed. */ - explicit LogEvent(const LogEvent&); + LogEvent(const LogEvent&); /** * Parses a log_msg into a LogEvent object. diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index ec602445d0ed..67a1a4720576 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -68,15 +68,12 @@ const int FIELD_ID_BUCKET_NUM = 6; const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 7; const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 8; -GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& metric, - const int conditionIndex, - const sp<ConditionWizard>& wizard, - const int whatMatcherIndex, - const sp<EventMatcherWizard>& matcherWizard, - const int pullTagId, - const int triggerAtomId, const int atomId, - const int64_t timeBaseNs, const int64_t startTimeNs, - const sp<StatsPullerManager>& pullerManager) +GaugeMetricProducer::GaugeMetricProducer( + const ConfigKey& key, const GaugeMetric& metric, const int conditionIndex, + const sp<ConditionWizard>& wizard, const int whatMatcherIndex, + const sp<EventMatcherWizard>& matcherWizard, const int pullTagId, const int triggerAtomId, + const int atomId, const int64_t timeBaseNs, const int64_t startTimeNs, + const sp<StatsPullerManager>& pullerManager) : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard), mWhatMatcherIndex(whatMatcherIndex), mEventMatcherWizard(matcherWizard), @@ -86,6 +83,8 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric mAtomId(atomId), mIsPulled(pullTagId != -1), mMinBucketSizeNs(metric.min_bucket_size_nanos()), + mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC + : StatsdStats::kPullMaxDelayNs), mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) != StatsdStats::kAtomDimensionKeySizeLimitMap.end() ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).first @@ -338,14 +337,24 @@ void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) { return; } vector<std::shared_ptr<LogEvent>> allData; - if (!mPullerManager->Pull(mPullTagId, timestampNs, &allData)) { + if (!mPullerManager->Pull(mPullTagId, &allData)) { ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs); return; } + const int64_t pullDelayNs = getElapsedRealtimeNs() - timestampNs; + if (pullDelayNs > mMaxPullDelayNs) { + ALOGE("Pull finish too late for atom %d", mPullTagId); + StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId); + StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs); + return; + } + StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs); for (const auto& data : allData) { - if (mEventMatcherWizard->matchLogEvent( - *data, mWhatMatcherIndex) == MatchingState::kMatched) { - onMatchedLogEventLocked(mWhatMatcherIndex, *data); + LogEvent localCopy = data->makeCopy(); + localCopy.setElapsedTimestampNs(timestampNs); + if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) == + MatchingState::kMatched) { + onMatchedLogEventLocked(mWhatMatcherIndex, localCopy); } } } diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h index 6e3530b0daf4..a1a506144d43 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.h +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h @@ -160,6 +160,8 @@ private: GaugeMetric::SamplingType mSamplingType; + const int64_t mMaxPullDelayNs; + // apply a whitelist on the original input std::shared_ptr<vector<FieldValue>> getGaugeFields(const LogEvent& event); diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index cf56e2d43385..9a8e3bd7b3eb 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -103,7 +103,9 @@ ValueMetricProducer::ValueMetricProducer( mValueDirection(metric.value_direction()), mSkipZeroDiffOutput(metric.skip_zero_diff_output()), mUseZeroDefaultBase(metric.use_zero_default_base()), - mHasGlobalBase(false) { + mHasGlobalBase(false), + mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC + : StatsdStats::kPullMaxDelayNs) { int64_t bucketSizeMills = 0; if (metric.has_bucket()) { bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()); @@ -340,19 +342,32 @@ void ValueMetricProducer::onConditionChangedLocked(const bool condition, void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) { vector<std::shared_ptr<LogEvent>> allData; - if (mPullerManager->Pull(mPullTagId, timestampNs, &allData)) { - for (const auto& data : allData) { - if (mEventMatcherWizard->matchLogEvent( - *data, mWhatMatcherIndex) == MatchingState::kMatched) { - onMatchedLogEventLocked(mWhatMatcherIndex, *data); - } - } - mHasGlobalBase = true; - } else { - // for pulled data, every pull is needed. So we reset the base if any - // pull fails. + if (!mPullerManager->Pull(mPullTagId, &allData)) { + ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs); + resetBase(); + return; + } + const int64_t pullDelayNs = getElapsedRealtimeNs() - timestampNs; + if (pullDelayNs > mMaxPullDelayNs) { + ALOGE("Pull finish too late for atom %d, longer than %lld", mPullTagId, + (long long)mMaxPullDelayNs); + StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId); + StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs); resetBase(); + return; + } + StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs); + + for (const auto& data : allData) { + // make a copy before doing and changes + LogEvent localCopy = data->makeCopy(); + localCopy.setElapsedTimestampNs(timestampNs); + if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) == + MatchingState::kMatched) { + onMatchedLogEventLocked(mWhatMatcherIndex, localCopy); + } } + mHasGlobalBase = true; } int64_t ValueMetricProducer::calcPreviousBucketEndTime(const int64_t currentTimeNs) { @@ -381,10 +396,11 @@ void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEven return; } for (const auto& data : allData) { - if (mEventMatcherWizard->matchLogEvent(*data, mWhatMatcherIndex) == + LogEvent localCopy = data->makeCopy(); + if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) == MatchingState::kMatched) { - data->setElapsedTimestampNs(bucketEndTime); - onMatchedLogEventLocked(mWhatMatcherIndex, *data); + localCopy.setElapsedTimestampNs(bucketEndTime); + onMatchedLogEventLocked(mWhatMatcherIndex, localCopy); } } mHasGlobalBase = true; diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index 4991af4cc75c..4865aee57187 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -183,6 +183,8 @@ private: // diff against. bool mHasGlobalBase; + const int64_t mMaxPullDelayNs; + FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition); FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering); FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset); @@ -207,6 +209,8 @@ private: FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBase); FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures); FRIEND_TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey); + FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFail); + FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate); }; } // namespace statsd diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp index dffff7a96269..22883f3c205a 100644 --- a/cmds/statsd/src/shell/ShellSubscriber.cpp +++ b/cmds/statsd/src/shell/ShellSubscriber.cpp @@ -131,8 +131,7 @@ void ShellSubscriber::startPull(int64_t token, int64_t intervalMillis) { VLOG("pull atom %d now", pullInfo.mPullerMatcher.atom_id()); vector<std::shared_ptr<LogEvent>> data; - mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), nowMillis * 1000000L, - &data); + mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), &data); VLOG("pulled %zu atoms", data.size()); if (data.size() > 0) { writeToOutputLocked(data, pullInfo.mPullerMatcher); diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h index 73e4d33d3e18..b8185d2a32d2 100644 --- a/cmds/statsd/src/socket/StatsSocketListener.h +++ b/cmds/statsd/src/socket/StatsSocketListener.h @@ -35,7 +35,7 @@ namespace statsd { class StatsSocketListener : public SocketListener, public virtual android::RefBase { public: - StatsSocketListener(const sp<LogListener>& listener); + explicit StatsSocketListener(const sp<LogListener>& listener); virtual ~StatsSocketListener(); @@ -51,4 +51,4 @@ private: }; } // namespace statsd } // namespace os -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto index 5a87e46097ae..e8de875a461b 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -401,6 +401,8 @@ message StatsdStatsReport { optional int64 average_pull_delay_nanos = 7; optional int64 max_pull_delay_nanos = 8; optional int64 data_error = 9; + optional int64 pull_timeout = 10; + optional int64 pull_exceed_max_delay = 11; } repeated PulledAtomStats pulled_atom_stats = 10; diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp index f1310db03d45..7de0bb3290a7 100644 --- a/cmds/statsd/src/stats_log_util.cpp +++ b/cmds/statsd/src/stats_log_util.cpp @@ -64,6 +64,8 @@ const int FIELD_ID_MAX_PULL_TIME_NANOS = 6; const int FIELD_ID_AVERAGE_PULL_DELAY_NANOS = 7; const int FIELD_ID_MAX_PULL_DELAY_NANOS = 8; const int FIELD_ID_DATA_ERROR = 9; +const int FIELD_ID_PULL_TIMEOUT = 10; +const int FIELD_ID_PULL_EXCEED_MAX_DELAY = 11; namespace { @@ -450,6 +452,10 @@ void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats> protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_DELAY_NANOS, (long long)pair.second.maxPullDelayNs); protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DATA_ERROR, (long long)pair.second.dataError); + protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT, + (long long)pair.second.pullTimeout); + protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_EXCEED_MAX_DELAY, + (long long)pair.second.pullExceedMaxDelay); protoOutput->end(token); } diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto index f485185cc9c2..381ac321a77a 100644 --- a/cmds/statsd/src/statsd_config.proto +++ b/cmds/statsd/src/statsd_config.proto @@ -240,7 +240,10 @@ message GaugeMetric { optional SamplingType sampling_type = 9 [default = RANDOM_ONE_SAMPLE] ; optional int64 min_bucket_size_nanos = 10; + optional int64 max_num_gauge_atoms_per_bucket = 11 [default = 10]; + + optional int32 max_pull_delay_sec = 13 [default = 10]; } message ValueMetric { @@ -285,6 +288,8 @@ message ValueMetric { optional ValueDirection value_direction = 13 [default = INCREASING]; optional bool skip_zero_diff_output = 14 [default = true]; + + optional int32 max_pull_delay_sec = 16 [default = 10]; } message Alert { diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp index 2d090e02a42a..d5c358d51a82 100644 --- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp +++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp @@ -48,6 +48,7 @@ StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type) { *gaugeMetric->mutable_dimensions_in_what() = CreateDimensions(android::util::TEMPERATURE, {2/* sensor name field */ }); gaugeMetric->set_bucket(FIVE_MINUTES); + gaugeMetric->set_max_pull_delay_sec(INT_MAX); config.set_hash_strings_in_metric_report(false); return config; @@ -57,7 +58,7 @@ StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type) { TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) { auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE); - int64_t baseTimeNs = 10 * NS_PER_SEC; + int64_t baseTimeNs = getElapsedRealtimeNs(); int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; @@ -202,7 +203,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) { TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) { auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE); - int64_t baseTimeNs = 10 * NS_PER_SEC; + int64_t baseTimeNs = getElapsedRealtimeNs(); int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; @@ -303,7 +304,7 @@ TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) { TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) { auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE); - int64_t baseTimeNs = 10 * NS_PER_SEC; + int64_t baseTimeNs = getElapsedRealtimeNs(); int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp index abf1ab176ea7..cab6eac81306 100644 --- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp @@ -50,6 +50,7 @@ StatsdConfig CreateStatsdConfig() { valueMetric->set_bucket(FIVE_MINUTES); valueMetric->set_use_absolute_value_on_reset(true); valueMetric->set_skip_zero_diff_output(false); + valueMetric->set_max_pull_delay_sec(INT_MAX); return config; } @@ -57,7 +58,7 @@ StatsdConfig CreateStatsdConfig() { TEST(ValueMetricE2eTest, TestPulledEvents) { auto config = CreateStatsdConfig(); - int64_t baseTimeNs = 10 * NS_PER_SEC; + int64_t baseTimeNs = getElapsedRealtimeNs(); int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000; @@ -163,7 +164,7 @@ TEST(ValueMetricE2eTest, TestPulledEvents) { TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) { auto config = CreateStatsdConfig(); - int64_t baseTimeNs = 10 * NS_PER_SEC; + int64_t baseTimeNs = getElapsedRealtimeNs(); int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000; diff --git a/cmds/statsd/tests/external/StatsPuller_test.cpp b/cmds/statsd/tests/external/StatsPuller_test.cpp new file mode 100644 index 000000000000..76e2097a90b8 --- /dev/null +++ b/cmds/statsd/tests/external/StatsPuller_test.cpp @@ -0,0 +1,227 @@ +// 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. + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <stdio.h> +#include <chrono> +#include <thread> +#include <vector> +#include "../metrics/metrics_test_helper.h" +#include "src/stats_log_util.h" +#include "tests/statsd_test_util.h" + +#ifdef __ANDROID__ + +namespace android { +namespace os { +namespace statsd { + +using namespace testing; +using std::make_shared; +using std::shared_ptr; +using std::vector; +using std::this_thread::sleep_for; +using testing::Contains; + +// cooldown time 1sec. +int pullTagId = 10014; + +bool pullSuccess; +vector<std::shared_ptr<LogEvent>> pullData; +long pullDelayNs; + +class FakePuller : public StatsPuller { +public: + FakePuller() : StatsPuller(pullTagId){}; + +private: + bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override { + (*data) = pullData; + sleep_for(std::chrono::nanoseconds(pullDelayNs)); + return pullSuccess; + } +}; + +FakePuller puller; + +shared_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) { + shared_ptr<LogEvent> event = make_shared<LogEvent>(pullTagId, eventTimeNs); + event->write(value); + event->init(); + return event; +} + +class StatsPullerTest : public ::testing::Test { +public: + StatsPullerTest() { + } + + void SetUp() override { + puller.ForceClearCache(); + pullSuccess = false; + pullDelayNs = 0; + pullData.clear(); + } +}; + +TEST_F(StatsPullerTest, PullSucces) { + pullData.push_back(createSimpleEvent(1111L, 33)); + + pullSuccess = true; + + vector<std::shared_ptr<LogEvent>> dataHolder; + EXPECT_TRUE(puller.Pull(&dataHolder)); + EXPECT_EQ(1, dataHolder.size()); + EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId()); + EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs()); + EXPECT_EQ(1, dataHolder[0]->size()); + EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value); + + sleep_for(std::chrono::seconds(1)); + + pullData.clear(); + pullData.push_back(createSimpleEvent(2222L, 44)); + + pullSuccess = true; + + EXPECT_TRUE(puller.Pull(&dataHolder)); + EXPECT_EQ(1, dataHolder.size()); + EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId()); + EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs()); + EXPECT_EQ(1, dataHolder[0]->size()); + EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value); +} + +TEST_F(StatsPullerTest, PullFailAfterSuccess) { + pullData.push_back(createSimpleEvent(1111L, 33)); + + pullSuccess = true; + + vector<std::shared_ptr<LogEvent>> dataHolder; + EXPECT_TRUE(puller.Pull(&dataHolder)); + EXPECT_EQ(1, dataHolder.size()); + EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId()); + EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs()); + EXPECT_EQ(1, dataHolder[0]->size()); + EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value); + + sleep_for(std::chrono::seconds(1)); + + pullData.clear(); + pullData.push_back(createSimpleEvent(2222L, 44)); + + pullSuccess = false; + dataHolder.clear(); + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); + + pullSuccess = true; + dataHolder.clear(); + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); +} + +// Test pull takes longer than timeout, 2nd pull happens shorter than cooldown +TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) { + pullData.push_back(createSimpleEvent(1111L, 33)); + pullSuccess = true; + // timeout is 0.5 + pullDelayNs = (long)(0.8 * NS_PER_SEC); + + vector<std::shared_ptr<LogEvent>> dataHolder; + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); + + pullData.clear(); + pullData.push_back(createSimpleEvent(2222L, 44)); + + pullSuccess = true; + dataHolder.clear(); + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); +} + +TEST_F(StatsPullerTest, PullFail) { + pullData.push_back(createSimpleEvent(1111L, 33)); + + pullSuccess = false; + + vector<std::shared_ptr<LogEvent>> dataHolder; + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); +} + +TEST_F(StatsPullerTest, PullTakeTooLong) { + pullData.push_back(createSimpleEvent(1111L, 33)); + + pullSuccess = true; + pullDelayNs = NS_PER_SEC; + + vector<std::shared_ptr<LogEvent>> dataHolder; + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); +} + +TEST_F(StatsPullerTest, PullTooFast) { + pullData.push_back(createSimpleEvent(1111L, 33)); + + pullSuccess = true; + + vector<std::shared_ptr<LogEvent>> dataHolder; + EXPECT_TRUE(puller.Pull(&dataHolder)); + EXPECT_EQ(1, dataHolder.size()); + EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId()); + EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs()); + EXPECT_EQ(1, dataHolder[0]->size()); + EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value); + + pullData.clear(); + pullData.push_back(createSimpleEvent(2222L, 44)); + + pullSuccess = true; + + dataHolder.clear(); + EXPECT_TRUE(puller.Pull(&dataHolder)); + EXPECT_EQ(1, dataHolder.size()); + EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId()); + EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs()); + EXPECT_EQ(1, dataHolder[0]->size()); + EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value); +} + +TEST_F(StatsPullerTest, PullFailsAndTooFast) { + pullData.push_back(createSimpleEvent(1111L, 33)); + + pullSuccess = false; + + vector<std::shared_ptr<LogEvent>> dataHolder; + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); + + pullData.clear(); + pullData.push_back(createSimpleEvent(2222L, 44)); + + pullSuccess = true; + + EXPECT_FALSE(puller.Pull(&dataHolder)); + EXPECT_EQ(0, dataHolder.size()); +} + +} // namespace statsd +} // namespace os +} // namespace android +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index 67a9f7fd8aaf..2799107c53d2 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -90,6 +90,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) { metric.set_id(metricId); metric.set_bucket(ONE_MINUTE); metric.mutable_gauge_fields_filter()->set_include_all(false); + metric.set_max_pull_delay_sec(INT_MAX); auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields(); gaugeFieldMatcher->set_field(tagId); gaugeFieldMatcher->add_child()->set_field(1); @@ -106,9 +107,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10); event->write(3); @@ -266,6 +266,7 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { GaugeMetric metric; metric.set_id(metricId); metric.set_bucket(ONE_MINUTE); + metric.set_max_pull_delay_sec(INT_MAX); auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields(); gaugeFieldMatcher->set_field(tagId); gaugeFieldMatcher->add_child()->set_field(2); @@ -281,10 +282,9 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) + EXPECT_CALL(*pullerManager, Pull(tagId, _)) .WillOnce(Return(false)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, eventUpgradeTimeNs); event->write("some value"); @@ -341,6 +341,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) { GaugeMetric metric; metric.set_id(metricId); metric.set_bucket(ONE_MINUTE); + metric.set_max_pull_delay_sec(INT_MAX); auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields(); gaugeFieldMatcher->set_field(tagId); gaugeFieldMatcher->add_child()->set_field(2); @@ -357,9 +358,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10); event->write("some value"); @@ -420,6 +420,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) { metric.set_bucket(ONE_MINUTE); metric.mutable_gauge_fields_filter()->set_include_all(true); metric.set_condition(StringToId("APP_DIED")); + metric.set_max_pull_delay_sec(INT_MAX); auto dim = metric.mutable_dimensions_in_what(); dim->set_field(tagId); dim->add_child()->set_field(1); @@ -454,9 +455,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10); event->write(1000); @@ -502,11 +502,12 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false)); + EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false)); GaugeMetric metric; metric.set_id(metricId); metric.set_bucket(ONE_MINUTE); + metric.set_max_pull_delay_sec(INT_MAX); auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields(); gaugeFieldMatcher->set_field(tagId); gaugeFieldMatcher->add_child()->set_field(2); @@ -591,6 +592,7 @@ TEST(GaugeMetricProducerTest, TestPullOnTrigger) { metric.set_bucket(ONE_MINUTE); metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES); metric.mutable_gauge_fields_filter()->set_include_all(false); + metric.set_max_pull_delay_sec(INT_MAX); auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields(); gaugeFieldMatcher->set_field(tagId); gaugeFieldMatcher->add_child()->set_field(1); @@ -604,9 +606,8 @@ TEST(GaugeMetricProducerTest, TestPullOnTrigger) { new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10); event->write(4); @@ -614,8 +615,7 @@ TEST(GaugeMetricProducerTest, TestPullOnTrigger) { data->push_back(event); return true; })) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20); event->write(5); @@ -664,6 +664,7 @@ TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) { metric.set_bucket(ONE_MINUTE); metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES); metric.mutable_gauge_fields_filter()->set_include_all(true); + metric.set_max_pull_delay_sec(INT_MAX); auto dimensionMatcher = metric.mutable_dimensions_in_what(); // use field 1 as dimension. dimensionMatcher->set_field(tagId); @@ -678,9 +679,8 @@ TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) { new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3); event->write(3); @@ -689,8 +689,7 @@ TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) { data->push_back(event); return true; })) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10); event->write(4); @@ -699,8 +698,7 @@ TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) { data->push_back(event); return true; })) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20); event->write(4); diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index 55245033e762..67570fc2ab51 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -125,6 +125,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { metric.set_bucket(ONE_MINUTE); metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -136,9 +137,8 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); event->write(tagId); @@ -218,6 +218,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { metric.set_bucket(ONE_MINUTE); metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -232,9 +233,8 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); event->write(3); @@ -315,6 +315,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); metric.set_use_absolute_value_on_reset(true); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -326,7 +327,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true)); + EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true)); ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex, eventMatcherWizard, tagId, @@ -393,6 +394,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { metric.set_bucket(ONE_MINUTE); metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -404,7 +406,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false)); + EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false)); ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex, eventMatcherWizard, tagId, @@ -469,6 +471,7 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -481,9 +484,8 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8); event->write(tagId); @@ -492,8 +494,7 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { data->push_back(event); return true; })) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); event->write(tagId); @@ -599,6 +600,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { metric.set_bucket(ONE_MINUTE); metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -610,10 +612,9 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) + EXPECT_CALL(*pullerManager, Pull(tagId, _)) .WillOnce(Return(true)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 149); event->write(tagId); @@ -661,6 +662,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) { metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -672,9 +674,8 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1); event->write(tagId); @@ -683,8 +684,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) { data->push_back(event); return true; })) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100); event->write(tagId); @@ -924,6 +924,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { metric.set_bucket(ONE_MINUTE); metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -935,7 +936,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true)); + EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true)); ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex, eventMatcherWizard, tagId, @@ -1012,6 +1013,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -1024,10 +1026,9 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) + EXPECT_CALL(*pullerManager, Pull(tagId, _)) // condition becomes true - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8); event->write(tagId); @@ -1037,8 +1038,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { return true; })) // condition becomes false - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); event->write(tagId); @@ -1098,6 +1098,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { metric.mutable_value_field()->set_field(tagId); metric.mutable_value_field()->add_child()->set_field(2); metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -1110,10 +1111,9 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillRepeatedly(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) + EXPECT_CALL(*pullerManager, Pull(tagId, _)) // condition becomes true - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8); event->write(tagId); @@ -1123,8 +1123,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { return true; })) // condition becomes false - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); event->write(tagId); @@ -1134,8 +1133,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { return true; })) // condition becomes true again - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 25); event->write(tagId); @@ -1480,6 +1478,7 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) { metric.mutable_dimensions_in_what()->set_field(tagId); metric.mutable_dimensions_in_what()->add_child()->set_field(1); metric.set_use_zero_default_base(true); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -1491,9 +1490,8 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); event->write(1); @@ -1565,6 +1563,7 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { metric.mutable_dimensions_in_what()->set_field(tagId); metric.mutable_dimensions_in_what()->add_child()->set_field(1); metric.set_use_zero_default_base(true); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -1576,9 +1575,8 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); event->write(1); @@ -1692,6 +1690,7 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { metric.mutable_value_field()->add_child()->set_field(2); metric.mutable_dimensions_in_what()->set_field(tagId); metric.mutable_dimensions_in_what()->add_child()->set_field(1); + metric.set_max_pull_delay_sec(INT_MAX); UidMap uidMap; SimpleAtomMatcher atomMatcher; @@ -1703,9 +1702,8 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); - EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) - .WillOnce(Invoke([](int tagId, int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data) { + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { data->clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); event->write(1); @@ -1804,6 +1802,128 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); } +TEST(ValueMetricProducerTest, TestResetBaseOnPullFail) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); + + UidMap uidMap; + SimpleAtomMatcher atomMatcher; + atomMatcher.set_atom_id(tagId); + sp<EventMatcherWizard> eventMatcherWizard = + new EventMatcherWizard({new SimpleLogMatchingTracker( + atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8); + event->write(tagId); + event->write(100); + event->init(); + data->push_back(event); + return true; + })) + .WillOnce(Return(false)); + + ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + valueProducer.onConditionChanged(true, bucketStartTimeNs + 8); + + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + ValueMetricProducer::Interval& curInterval = + valueProducer.mCurrentSlicedBucket.begin()->second[0]; + EXPECT_EQ(true, curInterval.hasBase); + EXPECT_EQ(100, curInterval.base.long_value); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(0UL, valueProducer.mPastBuckets.size()); + + valueProducer.onConditionChanged(false, bucketStartTimeNs + 20); + + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(false, curInterval.hasBase); + EXPECT_EQ(false, valueProducer.mHasGlobalBase); +} + +TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(0); + + UidMap uidMap; + SimpleAtomMatcher atomMatcher; + atomMatcher.set_atom_id(tagId); + sp<EventMatcherWizard> eventMatcherWizard = + new EventMatcherWizard({new SimpleLogMatchingTracker( + atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); + event->write(tagId); + event->write(120); + event->init(); + data->push_back(event); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + valueProducer.mCondition = true; + valueProducer.mHasGlobalBase = true; + + vector<shared_ptr<LogEvent>> allData; + allData.clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); + event->write(1); + event->write(110); + event->init(); + allData.push_back(event); + valueProducer.onDataPulled(allData); + + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + ValueMetricProducer::Interval& curInterval = + valueProducer.mCurrentSlicedBucket.begin()->second[0]; + EXPECT_EQ(true, curInterval.hasBase); + EXPECT_EQ(110, curInterval.base.long_value); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(0UL, valueProducer.mPastBuckets.size()); + EXPECT_EQ(true, valueProducer.mHasGlobalBase); + + valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1); + + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(false, curInterval.hasBase); + EXPECT_EQ(false, valueProducer.mHasGlobalBase); +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h index 5afaba6671fa..97c107228f9c 100644 --- a/cmds/statsd/tests/metrics/metrics_test_helper.h +++ b/cmds/statsd/tests/metrics/metrics_test_helper.h @@ -38,8 +38,7 @@ public: MOCK_METHOD4(RegisterReceiver, void(int tagId, wp<PullDataReceiver> receiver, int64_t nextPulltimeNs, int64_t intervalNs)); MOCK_METHOD2(UnRegisterReceiver, void(int tagId, wp<PullDataReceiver> receiver)); - MOCK_METHOD3(Pull, bool(const int pullCode, const int64_t timeNs, - vector<std::shared_ptr<LogEvent>>* data)); + MOCK_METHOD2(Pull, bool(const int pullCode, vector<std::shared_ptr<LogEvent>>* data)); }; class MockUidMap : public UidMap { diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp index dd00561854fb..a184f5672d65 100644 --- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp +++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp @@ -189,23 +189,22 @@ TEST(ShellSubscriberTest, testPulledSubscription) { sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); - EXPECT_CALL(*pullerManager, Pull(10016, _, _)) - .WillRepeatedly( - Invoke([](int tagId, int64_t timeNs, vector<std::shared_ptr<LogEvent>>* data) { - data->clear(); - shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, timeNs); - event->write(kUid1); - event->write(kCpuTime1); - event->init(); - data->push_back(event); - // another event - event = make_shared<LogEvent>(tagId, timeNs); - event->write(kUid2); - event->write(kCpuTime2); - event->init(); - data->push_back(event); - return true; - })); + EXPECT_CALL(*pullerManager, Pull(10016, _)) + .WillRepeatedly(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, 1111L); + event->write(kUid1); + event->write(kCpuTime1); + event->init(); + data->push_back(event); + // another event + event = make_shared<LogEvent>(tagId, 1111L); + event->write(kUid2); + event->write(kCpuTime2); + event->init(); + data->push_back(event); + return true; + })); runShellTest(getPulledConfig(), uidMap, pullerManager, vector<std::shared_ptr<LogEvent>>(), getExpectedShellData()); diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java index 3d5476d04701..d862e1c2babb 100644 --- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java +++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java @@ -16,14 +16,16 @@ package com.android.uiautomator.testrunner; +import android.app.ActivityThread; +import android.content.ContentResolver; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Bundle; -import android.os.RemoteException; -import android.os.ServiceManager; import android.os.SystemClock; +import android.provider.Settings; import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; -import com.android.internal.view.IInputMethodManager; import com.android.uiautomator.core.UiDevice; import junit.framework.TestCase; @@ -44,6 +46,8 @@ public class UiAutomatorTestCase extends TestCase { private static final String DISABLE_IME = "disable_ime"; private static final String DUMMY_IME_PACKAGE = "com.android.testing.dummyime"; + private static final int NOT_A_SUBTYPE_ID = -1; + private UiDevice mUiDevice; private Bundle mParams; private IAutomationSupport mAutomationSupport; @@ -124,9 +128,13 @@ public class UiAutomatorTestCase extends TestCase { SystemClock.sleep(ms); } - private void setDummyIme() throws RemoteException { - IInputMethodManager im = IInputMethodManager.Stub.asInterface(ServiceManager - .getService(Context.INPUT_METHOD_SERVICE)); + private void setDummyIme() { + Context context = ActivityThread.currentApplication(); + if (context == null) { + throw new RuntimeException("ActivityThread.currentApplication() is null."); + } + InputMethodManager im = (InputMethodManager) context.getSystemService( + Context.INPUT_METHOD_SERVICE); List<InputMethodInfo> infos = im.getInputMethodList(); String id = null; for (InputMethodInfo info : infos) { @@ -138,10 +146,17 @@ public class UiAutomatorTestCase extends TestCase { throw new RuntimeException(String.format( "Required testing fixture missing: IME package (%s)", DUMMY_IME_PACKAGE)); } - im.setInputMethod(null, id); + if (context.checkSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + != PackageManager.PERMISSION_GRANTED) { + return; + } + ContentResolver resolver = context.getContentResolver(); + Settings.Secure.putInt(resolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, + NOT_A_SUBTYPE_ID); + Settings.Secure.putString(resolver, Settings.Secure.DEFAULT_INPUT_METHOD, id); } - private void restoreActiveIme() throws RemoteException { + private void restoreActiveIme() { // TODO: figure out a way to restore active IME // Currently retrieving active IME requires querying secure settings provider, which is hard // to do without a Context; so the caveat here is that to make the post test device usable, diff --git a/config/hiddenapi-greylist-max-p.txt b/config/hiddenapi-greylist-max-p.txt index e69de29bb2d1..7840b186615f 100644 --- a/config/hiddenapi-greylist-max-p.txt +++ b/config/hiddenapi-greylist-max-p.txt @@ -0,0 +1,75 @@ +Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher; +Landroid/app/ISearchManager$Stub;-><init>()V +Landroid/app/IUiModeManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUiModeManager; +Landroid/app/IUiModeManager;->disableCarMode(I)V +Landroid/bluetooth/IBluetooth$Stub;-><init>()V +Landroid/bluetooth/IBluetoothA2dp$Stub;-><init>()V +Landroid/content/IIntentReceiver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentReceiver; +Landroid/content/IIntentSender$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentSender; +Landroid/net/IConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo; +Landroid/net/IConnectivityManager;->reportInetCondition(II)V +Landroid/os/BatteryStats$Counter;-><init>()V +Landroid/os/BatteryStats$HistoryItem;->clear()V +Landroid/os/BatteryStats$HistoryItem;->next:Landroid/os/BatteryStats$HistoryItem; +Landroid/os/BatteryStats$HistoryItem;->same(Landroid/os/BatteryStats$HistoryItem;)Z +Landroid/os/BatteryStats$HistoryItem;->setTo(JBLandroid/os/BatteryStats$HistoryItem;)V +Landroid/os/BatteryStats$HistoryItem;->setTo(Landroid/os/BatteryStats$HistoryItem;)V +Landroid/os/BatteryStats$Timer;-><init>()V +Landroid/os/BatteryStats$Uid$Pkg;-><init>()V +Landroid/os/BatteryStats$Uid$Proc;-><init>()V +Landroid/os/BatteryStats$Uid$Sensor;-><init>()V +Landroid/os/BatteryStats$Uid$Wakelock;-><init>()V +Landroid/os/BatteryStats;-><init>()V +Landroid/os/BatteryStats;->getMobileRadioActiveTime(JI)J +Landroid/os/BatteryStats;->getNetworkActivityBytes(II)J +Landroid/os/CancellationSignal;->mCancelInProgress:Z +Landroid/os/CancellationSignal;->mIsCanceled:Z +Landroid/os/CancellationSignal;->mOnCancelListener:Landroid/os/CancellationSignal$OnCancelListener; +Landroid/os/CancellationSignal;->mRemote:Landroid/os/ICancellationSignal; +Landroid/os/CancellationSignal;->waitForCancelFinishedLocked()V +Landroid/os/IPowerManager;->nap(J)V +Landroid/os/Parcel;->mCreators:Ljava/util/HashMap; +Landroid/os/PowerManager;->mHandler:Landroid/os/Handler; +Landroid/os/Process;->sendSignalQuiet(II)V +Landroid/os/Registrant;->getHandler()Landroid/os/Handler; +Landroid/os/RegistrantList;->get(I)Ljava/lang/Object; +Landroid/os/RemoteCallback;->mHandler:Landroid/os/Handler; +Landroid/os/storage/IObbActionListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IObbActionListener; +Landroid/os/SystemProperties;->native_add_change_callback()V +Landroid/os/SystemProperties;->native_get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; +Landroid/os/SystemProperties;->native_get_boolean(Ljava/lang/String;Z)Z +Landroid/os/SystemProperties;->native_get_int(Ljava/lang/String;I)I +Landroid/os/SystemProperties;->native_set(Ljava/lang/String;Ljava/lang/String;)V +Landroid/os/UserHandle;->formatUid(Ljava/io/PrintWriter;I)V +Landroid/os/WorkSource;->sGoneWork:Landroid/os/WorkSource; +Landroid/os/WorkSource;->sNewbWork:Landroid/os/WorkSource; +Landroid/os/WorkSource;->sTmpWorkSource:Landroid/os/WorkSource; +Landroid/os/WorkSource;->updateLocked(Landroid/os/WorkSource;ZZ)Z +Landroid/service/carrier/ICarrierMessagingCallback$Stub;-><init>()V +Landroid/service/carrier/ICarrierMessagingService;->filterSms(Landroid/service/carrier/MessagePdu;Ljava/lang/String;IILandroid/service/carrier/ICarrierMessagingCallback;)V +Landroid/telephony/CarrierMessagingServiceManager;-><init>()V +Landroid/view/IWindowManager;->setInTouchMode(Z)V +Landroid/view/IWindowManager;->showStrictModeViolation(Z)V +Lcom/android/internal/R$styleable;->AndroidManifestActivityAlias:[I +Lcom/android/internal/R$styleable;->AndroidManifestGrantUriPermission:[I +Lcom/android/internal/R$styleable;->AndroidManifestInstrumentation:[I +Lcom/android/internal/R$styleable;->AndroidManifestOriginalPackage:[I +Lcom/android/internal/R$styleable;->AndroidManifestPathPermission:[I +Lcom/android/internal/R$styleable;->AndroidManifestPermission:[I +Lcom/android/internal/R$styleable;->AndroidManifestPermissionGroup:[I +Lcom/android/internal/R$styleable;->AndroidManifestPermissionTree:[I +Lcom/android/internal/R$styleable;->AndroidManifestProtectedBroadcast:[I +Lcom/android/internal/R$styleable;->AndroidManifestSupportsScreens:[I +Lcom/android/internal/R$styleable;->AndroidManifestUsesConfiguration:[I +Lcom/android/internal/R$styleable;->AndroidManifestUsesFeature:[I +Lcom/android/internal/R$styleable;->CycleInterpolator:[I +Lcom/android/internal/R$styleable;->LinearLayout:[I +Lcom/android/internal/R$styleable;->MenuView:[I +Lcom/android/internal/R$styleable;->Searchable:[I +Lcom/android/internal/R$styleable;->SearchableActionKey:[I +Lcom/android/internal/telephony/IPhoneSubInfo$Stub;-><init>()V +Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallForwardingChanged(Z)V +Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellLocation(Landroid/os/Bundle;)V +Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataActivity(I)V +Lcom/android/internal/telephony/ITelephonyRegistry;->notifyOtaspChanged(I)V +Lcom/android/internal/view/BaseIWindow;-><init>()V diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 7bbeb16b1b24..7a993fd946f7 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -173,7 +173,6 @@ Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z Landroid/app/IInstrumentationWatcher$Stub;-><init>()V -Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher; Landroid/app/IInstrumentationWatcher;->instrumentationStatus(Landroid/content/ComponentName;ILandroid/os/Bundle;)V Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z @@ -191,7 +190,6 @@ Landroid/app/INotificationManager;->getZenModeConfig()Landroid/service/notificat Landroid/app/IProcessObserver$Stub;-><init>()V Landroid/app/ISearchManager$Stub$Proxy;->getGlobalSearchActivity()Landroid/content/ComponentName; Landroid/app/ISearchManager$Stub$Proxy;->getWebSearchActivity()Landroid/content/ComponentName; -Landroid/app/ISearchManager$Stub;-><init>()V Landroid/app/ISearchManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/ISearchManager; Landroid/app/ISearchManager;->getGlobalSearchActivity()Landroid/content/ComponentName; Landroid/app/IServiceConnection$Stub$Proxy;-><init>(Landroid/os/IBinder;)V @@ -206,8 +204,6 @@ Landroid/app/IStopUserCallback;->userStopped(I)V Landroid/app/ITransientNotification$Stub;-><init>()V Landroid/app/ITransientNotification;->show(Landroid/os/IBinder;)V Landroid/app/IUiModeManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/app/IUiModeManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUiModeManager; -Landroid/app/IUiModeManager;->disableCarMode(I)V Landroid/app/IUserSwitchObserver$Stub;-><init>()V Landroid/app/IWallpaperManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IWallpaperManager; Landroid/app/IWallpaperManager;->getHeightHint(I)I @@ -250,7 +246,6 @@ Landroid/app/usage/IUsageStatsManager;->setAppInactive(Ljava/lang/String;ZI)V Landroid/app/UserSwitchObserver;-><init>()V Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAddress()Ljava/lang/String; Landroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I -Landroid/bluetooth/IBluetooth$Stub;-><init>()V Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth; Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_enable:I Landroid/bluetooth/IBluetooth;->fetchRemoteUuids(Landroid/bluetooth/BluetoothDevice;)Z @@ -258,7 +253,6 @@ Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String; Landroid/bluetooth/IBluetooth;->getRemoteAlias(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String; Landroid/bluetooth/IBluetooth;->isEnabled()Z Landroid/bluetooth/IBluetooth;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V -Landroid/bluetooth/IBluetoothA2dp$Stub;-><init>()V Landroid/bluetooth/IBluetoothA2dp$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dp; Landroid/bluetooth/IBluetoothA2dp;->connect(Landroid/bluetooth/BluetoothDevice;)Z Landroid/bluetooth/IBluetoothA2dp;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z @@ -307,9 +301,7 @@ Landroid/content/IContentService;->setMasterSyncAutomatically(Z)V Landroid/content/IIntentReceiver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/content/IIntentReceiver$Stub$Proxy;->mRemote:Landroid/os/IBinder; Landroid/content/IIntentReceiver$Stub;-><init>()V -Landroid/content/IIntentReceiver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentReceiver; Landroid/content/IIntentReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V -Landroid/content/IIntentSender$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentSender; Landroid/content/IOnPrimaryClipChangedListener$Stub;-><init>()V Landroid/content/IOnPrimaryClipChangedListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IOnPrimaryClipChangedListener; Landroid/content/IRestrictionsManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IRestrictionsManager; @@ -554,13 +546,11 @@ Landroid/net/IConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkIn Landroid/net/IConnectivityManager;->getAllNetworkInfo()[Landroid/net/NetworkInfo; Landroid/net/IConnectivityManager;->getAllNetworkState()[Landroid/net/NetworkState; Landroid/net/IConnectivityManager;->getLastTetherError(Ljava/lang/String;)I -Landroid/net/IConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo; Landroid/net/IConnectivityManager;->getTetherableIfaces()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetherableUsbRegexs()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetherableWifiRegexs()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String; -Landroid/net/IConnectivityManager;->reportInetCondition(II)V Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd; Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V @@ -634,7 +624,6 @@ Landroid/os/BatteryManager;->EXTRA_CHARGE_COUNTER:Ljava/lang/String; Landroid/os/BatteryManager;->EXTRA_INVALID_CHARGER:Ljava/lang/String; Landroid/os/BatteryManager;->EXTRA_MAX_CHARGING_CURRENT:Ljava/lang/String; Landroid/os/BatteryManager;->EXTRA_MAX_CHARGING_VOLTAGE:Ljava/lang/String; -Landroid/os/BatteryStats$Counter;-><init>()V Landroid/os/BatteryStats$Counter;->getCountLocked(I)I Landroid/os/BatteryStats$HistoryItem;-><init>()V Landroid/os/BatteryStats$HistoryItem;->batteryHealth:B @@ -642,41 +631,31 @@ Landroid/os/BatteryStats$HistoryItem;->batteryLevel:B Landroid/os/BatteryStats$HistoryItem;->batteryPlugType:B Landroid/os/BatteryStats$HistoryItem;->batteryStatus:B Landroid/os/BatteryStats$HistoryItem;->batteryVoltage:C -Landroid/os/BatteryStats$HistoryItem;->clear()V Landroid/os/BatteryStats$HistoryItem;->cmd:B Landroid/os/BatteryStats$HistoryItem;->CMD_UPDATE:B -Landroid/os/BatteryStats$HistoryItem;->next:Landroid/os/BatteryStats$HistoryItem; -Landroid/os/BatteryStats$HistoryItem;->same(Landroid/os/BatteryStats$HistoryItem;)Z -Landroid/os/BatteryStats$HistoryItem;->setTo(JBLandroid/os/BatteryStats$HistoryItem;)V -Landroid/os/BatteryStats$HistoryItem;->setTo(Landroid/os/BatteryStats$HistoryItem;)V Landroid/os/BatteryStats$HistoryItem;->states2:I Landroid/os/BatteryStats$HistoryItem;->states:I Landroid/os/BatteryStats$HistoryItem;->time:J -Landroid/os/BatteryStats$Timer;-><init>()V Landroid/os/BatteryStats$Timer;->getCountLocked(I)I Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStarts(I)I Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStartTime(JI)J -Landroid/os/BatteryStats$Uid$Pkg;-><init>()V Landroid/os/BatteryStats$Uid$Pkg;->getServiceStats()Landroid/util/ArrayMap; Landroid/os/BatteryStats$Uid$Pkg;->getWakeupAlarmStats()Landroid/util/ArrayMap; Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;-><init>()V Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->overTime:J Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->type:I Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->usedTime:J -Landroid/os/BatteryStats$Uid$Proc;-><init>()V Landroid/os/BatteryStats$Uid$Proc;->countExcessivePowers()I Landroid/os/BatteryStats$Uid$Proc;->getExcessivePower(I)Landroid/os/BatteryStats$Uid$Proc$ExcessivePower; Landroid/os/BatteryStats$Uid$Proc;->getForegroundTime(I)J Landroid/os/BatteryStats$Uid$Proc;->getStarts(I)I Landroid/os/BatteryStats$Uid$Proc;->getSystemTime(I)J Landroid/os/BatteryStats$Uid$Proc;->getUserTime(I)J -Landroid/os/BatteryStats$Uid$Sensor;-><init>()V Landroid/os/BatteryStats$Uid$Sensor;->getHandle()I Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer; Landroid/os/BatteryStats$Uid$Sensor;->GPS:I -Landroid/os/BatteryStats$Uid$Wakelock;-><init>()V Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer; Landroid/os/BatteryStats$Uid;-><init>()V Landroid/os/BatteryStats$Uid;->getAudioTurnedOnTimer()Landroid/os/BatteryStats$Timer; @@ -693,7 +672,6 @@ Landroid/os/BatteryStats$Uid;->getWifiBatchedScanTime(IJI)J Landroid/os/BatteryStats$Uid;->getWifiMulticastTime(JI)J Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J Landroid/os/BatteryStats$Uid;->getWifiScanTime(JI)J -Landroid/os/BatteryStats;-><init>()V Landroid/os/BatteryStats;->computeBatteryRealtime(JI)J Landroid/os/BatteryStats;->computeBatteryTimeRemaining(J)J Landroid/os/BatteryStats;->computeBatteryUptime(JI)J @@ -701,8 +679,6 @@ Landroid/os/BatteryStats;->computeChargeTimeRemaining(J)J Landroid/os/BatteryStats;->dumpLine(Ljava/io/PrintWriter;ILjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V Landroid/os/BatteryStats;->getBatteryUptime(J)J Landroid/os/BatteryStats;->getGlobalWifiRunningTime(JI)J -Landroid/os/BatteryStats;->getMobileRadioActiveTime(JI)J -Landroid/os/BatteryStats;->getNetworkActivityBytes(II)J Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z Landroid/os/BatteryStats;->getPhoneOnTime(JI)J Landroid/os/BatteryStats;->getPhoneSignalStrengthTime(IJI)J @@ -733,11 +709,6 @@ Landroid/os/Bundle;->getSize()I Landroid/os/Bundle;->putIBinder(Ljava/lang/String;Landroid/os/IBinder;)V Landroid/os/Bundle;->putParcelableList(Ljava/lang/String;Ljava/util/List;)V Landroid/os/Bundle;->setDefusable(Landroid/os/Bundle;Z)Landroid/os/Bundle; -Landroid/os/CancellationSignal;->mCancelInProgress:Z -Landroid/os/CancellationSignal;->mIsCanceled:Z -Landroid/os/CancellationSignal;->mOnCancelListener:Landroid/os/CancellationSignal$OnCancelListener; -Landroid/os/CancellationSignal;->mRemote:Landroid/os/ICancellationSignal; -Landroid/os/CancellationSignal;->waitForCancelFinishedLocked()V Landroid/os/Debug$MemoryInfo;->dalvikPrivateClean:I Landroid/os/Debug$MemoryInfo;->dalvikRss:I Landroid/os/Debug$MemoryInfo;->dalvikSharedClean:I @@ -864,7 +835,6 @@ Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I Landroid/os/IPowerManager;->goToSleep(JII)V Landroid/os/IPowerManager;->isInteractive()Z -Landroid/os/IPowerManager;->nap(J)V Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V Landroid/os/IPowerManager;->userActivity(JII)V @@ -912,7 +882,6 @@ Landroid/os/MessageQueue;->next()Landroid/os/Message; Landroid/os/Parcel$ReadWriteHelper;-><init>()V Landroid/os/Parcel;->getGlobalAllocCount()J Landroid/os/Parcel;->getGlobalAllocSize()J -Landroid/os/Parcel;->mCreators:Ljava/util/HashMap; Landroid/os/Parcel;->mNativePtr:J Landroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V Landroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet; @@ -953,7 +922,6 @@ Landroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I Landroid/os/PowerManager;->goToSleep(JII)V Landroid/os/PowerManager;->GO_TO_SLEEP_REASON_TIMEOUT:I Landroid/os/PowerManager;->isLightDeviceIdleMode()Z -Landroid/os/PowerManager;->mHandler:Landroid/os/Handler; Landroid/os/PowerManager;->mService:Landroid/os/IPowerManager; Landroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V @@ -985,7 +953,6 @@ Landroid/os/Process;->PROC_ZERO_TERM:I Landroid/os/Process;->readProcFile(Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z Landroid/os/Process;->readProcLines(Ljava/lang/String;[Ljava/lang/String;[J)V Landroid/os/Process;->ROOT_UID:I -Landroid/os/Process;->sendSignalQuiet(II)V Landroid/os/Process;->setArgV0(Ljava/lang/String;)V Landroid/os/Process;->setProcessGroup(II)V Landroid/os/Process;->SHELL_UID:I @@ -994,7 +961,6 @@ Landroid/os/Process;->WIFI_UID:I Landroid/os/RecoverySystem;->verifyPackageCompatibility(Ljava/io/InputStream;)Z Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V Landroid/os/Registrant;->clear()V -Landroid/os/Registrant;->getHandler()Landroid/os/Handler; Landroid/os/Registrant;->messageForRegistrant()Landroid/os/Message; Landroid/os/Registrant;->notifyRegistrant()V Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V @@ -1003,14 +969,12 @@ Landroid/os/RegistrantList;-><init>()V Landroid/os/RegistrantList;->add(Landroid/os/Handler;ILjava/lang/Object;)V Landroid/os/RegistrantList;->add(Landroid/os/Registrant;)V Landroid/os/RegistrantList;->addUnique(Landroid/os/Handler;ILjava/lang/Object;)V -Landroid/os/RegistrantList;->get(I)Ljava/lang/Object; Landroid/os/RegistrantList;->notifyRegistrants()V Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V Landroid/os/RegistrantList;->notifyResult(Ljava/lang/Object;)V Landroid/os/RegistrantList;->remove(Landroid/os/Handler;)V Landroid/os/RegistrantList;->removeCleared()V Landroid/os/RegistrantList;->size()I -Landroid/os/RemoteCallback;->mHandler:Landroid/os/Handler; Landroid/os/RemoteCallbackList;->mCallbacks:Landroid/util/ArrayMap; Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException; Landroid/os/SELinux;->checkSELinuxAccess(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z @@ -1039,7 +1003,6 @@ Landroid/os/SharedMemory;->getFd()I Landroid/os/ShellCommand;->peekNextArg()Ljava/lang/String; Landroid/os/StatFs;->mStat:Landroid/system/StructStatVfs; Landroid/os/storage/IObbActionListener$Stub;-><init>()V -Landroid/os/storage/IObbActionListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IObbActionListener; Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager; Landroid/os/storage/StorageEventListener;-><init>()V @@ -1062,13 +1025,8 @@ Landroid/os/SystemClock;->currentThreadTimeMicro()J Landroid/os/SystemClock;->currentTimeMicro()J Landroid/os/SystemProperties;-><init>()V Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V -Landroid/os/SystemProperties;->native_add_change_callback()V Landroid/os/SystemProperties;->native_get(Ljava/lang/String;)Ljava/lang/String; -Landroid/os/SystemProperties;->native_get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; -Landroid/os/SystemProperties;->native_get_boolean(Ljava/lang/String;Z)Z -Landroid/os/SystemProperties;->native_get_int(Ljava/lang/String;I)I Landroid/os/SystemProperties;->native_get_long(Ljava/lang/String;J)J -Landroid/os/SystemProperties;->native_set(Ljava/lang/String;Ljava/lang/String;)V Landroid/os/SystemProperties;->PROP_NAME_MAX:I Landroid/os/SystemProperties;->reportSyspropChanged()V Landroid/os/SystemProperties;->sChangeCallbacks:Ljava/util/ArrayList; @@ -1108,7 +1066,6 @@ Landroid/os/UserHandle;->AID_ROOT:I Landroid/os/UserHandle;->AID_SHARED_GID_START:I Landroid/os/UserHandle;->CURRENT_OR_SELF:Landroid/os/UserHandle; Landroid/os/UserHandle;->ERR_GID:I -Landroid/os/UserHandle;->formatUid(Ljava/io/PrintWriter;I)V Landroid/os/UserHandle;->getAppIdFromSharedAppGid(I)I Landroid/os/UserHandle;->getCallingUserId()I Landroid/os/UserHandle;->getUid(II)I @@ -1169,10 +1126,6 @@ Landroid/os/WorkSource;-><init>(Landroid/os/Parcel;)V Landroid/os/WorkSource;->mNames:[Ljava/lang/String; Landroid/os/WorkSource;->mNum:I Landroid/os/WorkSource;->mUids:[I -Landroid/os/WorkSource;->sGoneWork:Landroid/os/WorkSource; -Landroid/os/WorkSource;->sNewbWork:Landroid/os/WorkSource; -Landroid/os/WorkSource;->sTmpWorkSource:Landroid/os/WorkSource; -Landroid/os/WorkSource;->updateLocked(Landroid/os/WorkSource;ZZ)Z Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/String;)V Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/Throwable;)V Landroid/preference/PreferenceGroupAdapter;->getItem(I)Landroid/preference/Preference; @@ -1465,8 +1418,6 @@ Landroid/security/keystore/IKeystoreService;->is_hardware_backed(Ljava/lang/Stri Landroid/security/keystore/IKeystoreService;->list(Ljava/lang/String;I)[Ljava/lang/String; Landroid/security/keystore/IKeystoreService;->reset()I Landroid/security/keystore/IKeystoreService;->ungrant(Ljava/lang/String;I)I -Landroid/service/carrier/ICarrierMessagingCallback$Stub;-><init>()V -Landroid/service/carrier/ICarrierMessagingService;->filterSms(Landroid/service/carrier/MessagePdu;Ljava/lang/String;IILandroid/service/carrier/ICarrierMessagingCallback;)V Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager; Landroid/service/dreams/IDreamManager;->awaken()V Landroid/service/dreams/IDreamManager;->dream()V @@ -1503,7 +1454,6 @@ Landroid/service/wallpaper/IWallpaperService$Stub;->asInterface(Landroid/os/IBin Landroid/speech/IRecognitionListener;->onEvent(ILandroid/os/Bundle;)V Landroid/telecom/Log;->i(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V Landroid/telecom/Log;->w(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V -Landroid/telephony/CarrierMessagingServiceManager;-><init>()V Landroid/telephony/ims/compat/feature/MMTelFeature;-><init>()V Landroid/telephony/ims/compat/ImsService;-><init>()V Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;-><init>()V @@ -1606,11 +1556,9 @@ Landroid/view/IWindowManager;->registerDockedStackListener(Landroid/view/IDocked Landroid/view/IWindowManager;->removeRotationWatcher(Landroid/view/IRotationWatcher;)V Landroid/view/IWindowManager;->setAnimationScale(IF)V Landroid/view/IWindowManager;->setAnimationScales([F)V -Landroid/view/IWindowManager;->setInTouchMode(Z)V Landroid/view/IWindowManager;->setNavBarVirtualKeyHapticFeedbackEnabled(Z)V Landroid/view/IWindowManager;->setShelfHeight(ZI)V Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)V -Landroid/view/IWindowManager;->showStrictModeViolation(Z)V Landroid/view/IWindowManager;->thawRotation()V Landroid/view/IWindowSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowSession; Landroid/view/IWindowSession;->finishDrawing(Landroid/view/IWindow;)V @@ -2106,7 +2054,6 @@ Lcom/android/internal/R$styleable;->AlertDialog:[I Lcom/android/internal/R$styleable;->AnalogClock:[I Lcom/android/internal/R$styleable;->AndroidManifest:[I Lcom/android/internal/R$styleable;->AndroidManifestActivity:[I -Lcom/android/internal/R$styleable;->AndroidManifestActivityAlias:[I Lcom/android/internal/R$styleable;->AndroidManifestActivity_allowTaskReparenting:I Lcom/android/internal/R$styleable;->AndroidManifestActivity_configChanges:I Lcom/android/internal/R$styleable;->AndroidManifestActivity_description:I @@ -2140,21 +2087,13 @@ Lcom/android/internal/R$styleable;->AndroidManifestApplication_supportsRtl:I Lcom/android/internal/R$styleable;->AndroidManifestApplication_theme:I Lcom/android/internal/R$styleable;->AndroidManifestApplication_uiOptions:I Lcom/android/internal/R$styleable;->AndroidManifestData:[I -Lcom/android/internal/R$styleable;->AndroidManifestGrantUriPermission:[I -Lcom/android/internal/R$styleable;->AndroidManifestInstrumentation:[I Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter:[I Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter_priority:I Lcom/android/internal/R$styleable;->AndroidManifestMetaData:[I Lcom/android/internal/R$styleable;->AndroidManifestMetaData_name:I Lcom/android/internal/R$styleable;->AndroidManifestMetaData_resource:I Lcom/android/internal/R$styleable;->AndroidManifestMetaData_value:I -Lcom/android/internal/R$styleable;->AndroidManifestOriginalPackage:[I Lcom/android/internal/R$styleable;->AndroidManifestPackageVerifier:[I -Lcom/android/internal/R$styleable;->AndroidManifestPathPermission:[I -Lcom/android/internal/R$styleable;->AndroidManifestPermission:[I -Lcom/android/internal/R$styleable;->AndroidManifestPermissionGroup:[I -Lcom/android/internal/R$styleable;->AndroidManifestPermissionTree:[I -Lcom/android/internal/R$styleable;->AndroidManifestProtectedBroadcast:[I Lcom/android/internal/R$styleable;->AndroidManifestProvider:[I Lcom/android/internal/R$styleable;->AndroidManifestService:[I Lcom/android/internal/R$styleable;->AndroidManifestService_enabled:I @@ -2162,9 +2101,6 @@ Lcom/android/internal/R$styleable;->AndroidManifestService_exported:I Lcom/android/internal/R$styleable;->AndroidManifestService_name:I Lcom/android/internal/R$styleable;->AndroidManifestService_permission:I Lcom/android/internal/R$styleable;->AndroidManifestService_process:I -Lcom/android/internal/R$styleable;->AndroidManifestSupportsScreens:[I -Lcom/android/internal/R$styleable;->AndroidManifestUsesConfiguration:[I -Lcom/android/internal/R$styleable;->AndroidManifestUsesFeature:[I Lcom/android/internal/R$styleable;->AndroidManifestUsesLibrary:[I Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission:[I Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission_name:I @@ -2187,7 +2123,6 @@ Lcom/android/internal/R$styleable;->CompoundButton:[I Lcom/android/internal/R$styleable;->CompoundButton_button:I Lcom/android/internal/R$styleable;->CompoundButton_checked:I Lcom/android/internal/R$styleable;->ContactsDataKind:[I -Lcom/android/internal/R$styleable;->CycleInterpolator:[I Lcom/android/internal/R$styleable;->DatePicker:[I Lcom/android/internal/R$styleable;->DialogPreference:[I Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I @@ -2207,7 +2142,6 @@ Lcom/android/internal/R$styleable;->Keyboard:[I Lcom/android/internal/R$styleable;->KeyboardView:[I Lcom/android/internal/R$styleable;->Keyboard_Key:[I Lcom/android/internal/R$styleable;->Keyboard_Row:[I -Lcom/android/internal/R$styleable;->LinearLayout:[I Lcom/android/internal/R$styleable;->ListPreference:[I Lcom/android/internal/R$styleable;->ListPreference_entries:I Lcom/android/internal/R$styleable;->ListView:[I @@ -2222,7 +2156,6 @@ Lcom/android/internal/R$styleable;->MapView:[I Lcom/android/internal/R$styleable;->MapView_apiKey:I Lcom/android/internal/R$styleable;->MenuGroup:[I Lcom/android/internal/R$styleable;->MenuItem:[I -Lcom/android/internal/R$styleable;->MenuView:[I Lcom/android/internal/R$styleable;->NumberPicker:[I Lcom/android/internal/R$styleable;->PopupWindow:[I Lcom/android/internal/R$styleable;->PopupWindow_popupAnimationStyle:I @@ -2249,8 +2182,6 @@ Lcom/android/internal/R$styleable;->QuickContactBadge:[I Lcom/android/internal/R$styleable;->RingtonePreference:[I Lcom/android/internal/R$styleable;->ScrollView:[I Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I -Lcom/android/internal/R$styleable;->Searchable:[I -Lcom/android/internal/R$styleable;->SearchableActionKey:[I Lcom/android/internal/R$styleable;->SelectionModeDrawables:[I Lcom/android/internal/R$styleable;->Switch:[I Lcom/android/internal/R$styleable;->SwitchPreference:[I @@ -2869,7 +2800,6 @@ Lcom/android/internal/telephony/dataconnection/DataConnection;->mNetworkInfo:Lan Lcom/android/internal/telephony/dataconnection/DataConnection;->mPhone:Lcom/android/internal/telephony/Phone; Lcom/android/internal/telephony/dataconnection/DataConnection;->mRilRat:I Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfConnected(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfDisconnectDcRetrying(Ljava/lang/String;)V Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;Z)V Lcom/android/internal/telephony/dataconnection/DataConnection;->onConnect(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)V Lcom/android/internal/telephony/dataconnection/DataConnection;->tearDownData(Ljava/lang/Object;)V @@ -2937,7 +2867,6 @@ Lcom/android/internal/telephony/DctConstants$State;->DISCONNECTING:Lcom/android/ Lcom/android/internal/telephony/DctConstants$State;->FAILED:Lcom/android/internal/telephony/DctConstants$State; Lcom/android/internal/telephony/DctConstants$State;->IDLE:Lcom/android/internal/telephony/DctConstants$State; Lcom/android/internal/telephony/DctConstants$State;->RETRYING:Lcom/android/internal/telephony/DctConstants$State; -Lcom/android/internal/telephony/DctConstants$State;->SCANNING:Lcom/android/internal/telephony/DctConstants$State; Lcom/android/internal/telephony/DctConstants$State;->values()[Lcom/android/internal/telephony/DctConstants$State; Lcom/android/internal/telephony/DefaultPhoneNotifier;->mRegistry:Lcom/android/internal/telephony/ITelephonyRegistry; Lcom/android/internal/telephony/DriverCall$State;->ACTIVE:Lcom/android/internal/telephony/DriverCall$State; @@ -3313,7 +3242,6 @@ Lcom/android/internal/telephony/IntRangeManager;->mRanges:Ljava/util/ArrayList; Lcom/android/internal/telephony/IPhoneStateListener$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneStateListener; Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String; -Lcom/android/internal/telephony/IPhoneSubInfo$Stub;-><init>()V Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneSubInfo; Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->TRANSACTION_getDeviceId:I Lcom/android/internal/telephony/IPhoneSubInfo;->getIccSerialNumber(Ljava/lang/String;)Ljava/lang/String; @@ -3360,13 +3288,9 @@ Lcom/android/internal/telephony/ITelephony;->updateServiceLocation()V Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry; Lcom/android/internal/telephony/ITelephonyRegistry;->listen(Ljava/lang/String;Lcom/android/internal/telephony/IPhoneStateListener;IZ)V -Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallForwardingChanged(Z)V Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellInfo(Ljava/util/List;)V -Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellLocation(Landroid/os/Bundle;)V -Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataActivity(I)V Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;Ljava/lang/String;)V -Lcom/android/internal/telephony/ITelephonyRegistry;->notifyOtaspChanged(I)V Lcom/android/internal/telephony/IWapPushManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IWapPushManager; Lcom/android/internal/telephony/IWapPushManager;->addPackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z Lcom/android/internal/telephony/IWapPushManager;->deletePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z @@ -4140,7 +4064,6 @@ 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/BaseIWindow;-><init>()V 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; diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 579144bbce73..26c2c0cfdd5d 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -2226,12 +2226,12 @@ public class AccountManager { } private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final IAccountManagerResponse mResponse; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final Handler mHandler; final AccountManagerCallback<Bundle> mCallback; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final Activity mActivity; public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) { super(new Callable<Bundle>() { @@ -2556,13 +2556,13 @@ public class AccountManager { } volatile AccountManagerFuture<Bundle> mFuture = null; final String mAccountType; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final String mAuthTokenType; final String[] mFeatures; final Bundle mAddAccountOptions; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final Bundle mLoginOptions; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final AccountManagerCallback<Bundle> mMyCallback; private volatile int mNumAccounts = 0; diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java index 6875867108de..2360cec5bde8 100644 --- a/core/java/android/accounts/AuthenticatorDescription.java +++ b/core/java/android/accounts/AuthenticatorDescription.java @@ -17,6 +17,7 @@ package android.accounts; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcelable; import android.os.Parcel; @@ -77,7 +78,7 @@ public class AuthenticatorDescription implements Parcelable { return new AuthenticatorDescription(type); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private AuthenticatorDescription(String type) { this.type = type; this.packageName = null; @@ -88,7 +89,7 @@ public class AuthenticatorDescription implements Parcelable { this.customTokens = false; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private AuthenticatorDescription(Parcel source) { this.type = source.readString(); this.packageName = source.readString(); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 48a767bee341..5b8261e38f1e 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -848,7 +848,7 @@ public class Activity extends ContextThemeWrapper @UnsupportedAppUsage /*package*/ boolean mWindowAdded = false; /*package*/ boolean mVisibleFromServer = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) /*package*/ boolean mVisibleFromClient = true; /*package*/ ActionBar mActionBar = null; private boolean mEnableDefaultActionBarUp; @@ -924,6 +924,9 @@ public class Activity extends ContextThemeWrapper private AutofillPopupWindow mAutofillPopupWindow; + /** @hide */ + boolean mEnterAnimationComplete; + private static native String getDlWarning(); /** Return the intent that started this activity. */ @@ -2328,6 +2331,7 @@ public class Activity extends ContextThemeWrapper } notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_STOP); } + mEnterAnimationComplete = false; } /** @@ -7085,6 +7089,8 @@ public class Activity extends ContextThemeWrapper * @hide */ public void dispatchEnterAnimationComplete() { + mEnterAnimationComplete = true; + mInstrumentation.onEnterAnimationComplete(); onEnterAnimationComplete(); if (getWindow() != null && getWindow().getDecorView() != null) { getWindow().getDecorView().getViewTreeObserver().dispatchOnEnterAnimationComplete(); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 84c778502393..d42326020323 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1976,6 +1976,32 @@ public class ActivityManager { } /** + * Check if the context is allowed to start an activity on specified display. Some launch + * restrictions may apply to secondary displays that are private, virtual, or owned by the + * system, in which case an activity start may throw a {@link SecurityException}. Call this + * method prior to starting an activity on a secondary display to check if the current context + * has access to it. + * + * @see ActivityOptions#setLaunchDisplayId(int) + * @see android.view.Display.FLAG_PRIVATE + * @see android.view.Display.TYPE_VIRTUAL + * + * @param context Source context, from which an activity will be started. + * @param displayId Target display id. + * @param intent Intent used to launch an activity. + * @return {@code true} if a call to start an activity on the target display is allowed for the + * provided context and no {@link SecurityException} will be thrown, {@code false} otherwise. + */ + public boolean isActivityStartAllowedOnDisplay(Context context, int displayId, Intent intent) { + try { + return getTaskService().isActivityStartAllowedOnDisplay(displayId, intent, + intent.resolveTypeIfNeeded(context.getContentResolver()), context.getUserId()); + } catch (RemoteException e) { + throw new RuntimeException("Failure from system", e); + } + } + + /** * Information you can retrieve about a particular Service that is * currently running in the system. */ diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java index 4d8c8563ad7c..7eab5dba5f82 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -430,4 +430,17 @@ public class ActivityTaskManager { e.rethrowFromSystemServer(); } } + + /** + * Makes the display with the given id a single task instance display. I.e the display can only + * contain one task. + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + public void setDisplayToSingleTaskInstance(int displayId) { + try { + getService().setDisplayToSingleTaskInstance(displayId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 497e193c38ec..8faf08a77355 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3497,7 +3497,7 @@ public final class ActivityThread extends ClientTransactionHandler { return sCurrentBroadcastIntent.get(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private void handleReceiver(ReceiverData data) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 680fed80d029..0b5776e89524 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -83,6 +83,9 @@ public class ActivityView extends ViewGroup { private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); private Surface mTmpSurface = new Surface(); + /** The ActivityView is only allowed to contain one task. */ + private final boolean mSingleTaskInstance; + @UnsupportedAppUsage public ActivityView(Context context) { this(context, null /* attrs */); @@ -93,7 +96,13 @@ public class ActivityView extends ViewGroup { } public ActivityView(Context context, AttributeSet attrs, int defStyle) { + this(context, attrs, defStyle, false /*singleTaskInstance*/); + } + + public ActivityView( + Context context, AttributeSet attrs, int defStyle, boolean singleTaskInstance) { super(context, attrs, defStyle); + mSingleTaskInstance = singleTaskInstance; mActivityTaskManager = ActivityTaskManager.getService(); mSurfaceView = new SurfaceView(context); @@ -379,6 +388,9 @@ public class ActivityView extends ViewGroup { try { wm.reparentDisplayContent(displayId, mRootSurfaceControl.getHandle()); wm.dontOverrideDisplayInfo(displayId); + if (mSingleTaskInstance) { + mActivityTaskManager.setDisplayToSingleTaskInstance(displayId); + } } catch (RemoteException e) { e.rethrowAsRuntimeException(); } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 17529a6dacf0..94983e1c3672 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2299,9 +2299,9 @@ public class ApplicationPackageManager extends PackageManager { } @Override - public boolean canSuspendPackage(String packageName) { + public String[] getUnsuspendablePackages(String[] packageNames) { try { - return mPM.canSuspendPackageForUser(packageName, mContext.getUserId()); + return mPM.getUnsuspendablePackagesForUser(packageNames, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index 6bcfb2e8fe9e..4bd935c0e924 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -130,7 +130,7 @@ public class Dialog implements DialogInterface, Window.Callback, private boolean mShowing = false; private boolean mCanceled = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Handler mHandler = new Handler(); private static final int DISMISS = 0x43; diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index dbc4e34decf4..4f121aa35f7c 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -390,7 +390,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene ViewGroup mContainer; // The View generated for this fragment. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) View mView; // Whether this fragment should defer starting until after other fragments diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index 777a4949a132..dd87dc330b65 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -119,6 +119,8 @@ interface IActivityTaskManager { in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options, IBinder permissionToken, boolean ignoreTargetSecurity, int userId); + boolean isActivityStartAllowedOnDisplay(int displayId, in Intent intent, in String resolvedType, + int userId); void unhandledBack(); boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask); @@ -450,4 +452,10 @@ interface IActivityTaskManager { * Clears launch params for given packages. */ void clearLaunchParamsForPackages(in List<String> packageNames); + + /** + * Makes the display with the given id a single task instance display. I.e the display can only + * contain one task. + */ + void setDisplayToSingleTaskInstance(int displayId); } diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 015bc6c4bb07..dda5569a26b3 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.hardware.input.InputManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; @@ -110,6 +111,7 @@ public class Instrumentation { private PerformanceCollector mPerformanceCollector; private Bundle mPerfMetrics = new Bundle(); private UiAutomation mUiAutomation; + private final Object mAnimationCompleteLock = new Object(); public Instrumentation() { } @@ -397,6 +399,31 @@ public class Instrumentation { idler.waitForIdle(); } + private void waitForEnterAnimationComplete(Activity activity) { + synchronized (mAnimationCompleteLock) { + long timeout = 5000; + try { + // We need to check that this specified Activity completed the animation, not just + // any Activity. If it was another Activity, then decrease the timeout by how long + // it's already waited and wait for the thread to wakeup again. + while (timeout > 0 && !activity.mEnterAnimationComplete) { + long startTime = System.currentTimeMillis(); + mAnimationCompleteLock.wait(timeout); + long totalTime = System.currentTimeMillis() - startTime; + timeout -= totalTime; + } + } catch (InterruptedException e) { + } + } + } + + /** @hide */ + public void onEnterAnimationComplete() { + synchronized (mAnimationCompleteLock) { + mAnimationCompleteLock.notifyAll(); + } + } + /** * Execute a call on the application's main thread, blocking until it is * complete. Useful for doing things that are not thread-safe, such as @@ -499,6 +526,7 @@ public class Instrumentation { } } while (mWaitingActivities.contains(aw)); + waitForEnterAnimationComplete(aw.activity); return aw.activity; } } @@ -2002,7 +2030,7 @@ public class Instrumentation { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static void checkStartActivityResult(int res, Object intent) { if (!ActivityManager.isStartResultFatalError(res)) { return; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index a782ced7f9f8..aad32532bbe8 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1638,46 +1638,6 @@ public class NotificationManager { return true; } - /** - * @hide - */ - public static boolean areAnyScreenOffEffectsSuppressed(int effects) { - for (int i = 0; i < SCREEN_OFF_SUPPRESSED_EFFECTS.length; i++) { - final int effect = SCREEN_OFF_SUPPRESSED_EFFECTS[i]; - if ((effects & effect) != 0) { - return true; - } - } - return false; - } - - /** - * @hide - */ - public static boolean areAnyScreenOnEffectsSuppressed(int effects) { - for (int i = 0; i < SCREEN_ON_SUPPRESSED_EFFECTS.length; i++) { - final int effect = SCREEN_ON_SUPPRESSED_EFFECTS[i]; - if ((effects & effect) != 0) { - return true; - } - } - return false; - } - - /** - * @hide - */ - public static int toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress) { - return toggleEffects(currentEffects, SCREEN_OFF_SUPPRESSED_EFFECTS, suppress); - } - - /** - * @hide - */ - public static int toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress) { - return toggleEffects(currentEffects, SCREEN_ON_SUPPRESSED_EFFECTS, suppress); - } - private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) { for (int i = 0; i < effects.length; i++) { final int effect = effects[i]; @@ -1837,6 +1797,41 @@ public class NotificationManager { return priorityMessageSenders; } + /** @hide **/ + public boolean showFullScreenIntents() { + return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0; + } + + /** @hide **/ + public boolean showLights() { + return (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0; + } + + /** @hide **/ + public boolean showPeeking() { + return (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0; + } + + /** @hide **/ + public boolean showStatusBarIcons() { + return (suppressedVisualEffects & SUPPRESSED_EFFECT_STATUS_BAR) == 0; + } + + /** @hide **/ + public boolean showAmbient() { + return (suppressedVisualEffects & SUPPRESSED_EFFECT_AMBIENT) == 0; + } + + /** @hide **/ + public boolean showBadges() { + return (suppressedVisualEffects & SUPPRESSED_EFFECT_BADGE) == 0; + } + + /** @hide **/ + public boolean showInNotificationList() { + return (suppressedVisualEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0; + } + /** * returns a deep copy of this policy * @hide diff --git a/core/java/android/app/ProgressDialog.java b/core/java/android/app/ProgressDialog.java index 1b10fd7cf86d..3193eb89ac80 100644 --- a/core/java/android/app/ProgressDialog.java +++ b/core/java/android/app/ProgressDialog.java @@ -22,6 +22,7 @@ import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -64,7 +65,7 @@ public class ProgressDialog extends AlertDialog { */ public static final int STYLE_HORIZONTAL = 1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private ProgressBar mProgress; @UnsupportedAppUsage private TextView mMessageView; diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java index 4335488777ba..d916c94ab6c5 100644 --- a/core/java/android/app/ResultInfo.java +++ b/core/java/android/app/ResultInfo.java @@ -18,6 +18,7 @@ package android.app; import android.annotation.UnsupportedAppUsage; import android.content.Intent; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -65,7 +66,7 @@ public class ResultInfo implements Parcelable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final Parcelable.Creator<ResultInfo> CREATOR = new Parcelable.Creator<ResultInfo>() { public ResultInfo createFromParcel(Parcel in) { diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 45e87e045ae2..3f6ebc8e63e9 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -49,6 +49,8 @@ import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ShortcutManager; import android.content.res.Resources; +import android.content.rollback.IRollbackManager; +import android.content.rollback.RollbackManager; import android.debug.AdbManager; import android.debug.IAdbManager; import android.hardware.ConsumerIrManager; @@ -98,6 +100,7 @@ import android.net.INetworkPolicyManager; import android.net.IpSecManager; import android.net.NetworkPolicyManager; import android.net.NetworkScoreManager; +import android.net.NetworkStack; import android.net.NetworkWatchlistManager; import android.net.lowpan.ILowpanManager; import android.net.lowpan.LowpanManager; @@ -315,6 +318,13 @@ final class SystemServiceRegistry { return new ConnectivityManager(context, service); }}); + registerService(Context.NETWORK_STACK_SERVICE, NetworkStack.class, + new StaticServiceFetcher<NetworkStack>() { + @Override + public NetworkStack createService() { + return new NetworkStack(); + }}); + registerService(Context.IPSEC_SERVICE, IpSecManager.class, new CachedServiceFetcher<IpSecManager>() { @Override @@ -1161,6 +1171,16 @@ final class SystemServiceRegistry { throws ServiceNotFoundException { return new RoleManager(ctx.getOuterContext()); }}); + + registerService(Context.ROLLBACK_SERVICE, RollbackManager.class, + new CachedServiceFetcher<RollbackManager>() { + @Override + public RollbackManager createService(ContextImpl ctx) + throws ServiceNotFoundException { + IBinder b = ServiceManager.getServiceOrThrow(Context.ROLLBACK_SERVICE); + return new RollbackManager(ctx.getOuterContext(), + IRollbackManager.Stub.asInterface(b)); + }}); //CHECKSTYLE:ON IndentationCheck } diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java index beb1c78388c9..121161e1a2f0 100644 --- a/core/java/android/app/admin/DeviceAdminInfo.java +++ b/core/java/android/app/admin/DeviceAdminInfo.java @@ -29,6 +29,7 @@ import android.content.res.Resources.NotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; @@ -174,7 +175,7 @@ public final class DeviceAdminInfo implements Parcelable { /** @hide */ public static class PolicyInfo { public final int ident; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public final String tag; public final int label; public final int description; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 03e5933d300d..f843262933ff 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -55,6 +55,7 @@ import android.net.PrivateDnsConnectivityChecker; import android.net.ProxyInfo; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.Parcelable; @@ -2487,7 +2488,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordQuality(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -2553,7 +2554,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordMinimumLength(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -2623,7 +2624,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordMinimumUpperCase(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -2693,7 +2694,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordMinimumLowerCase(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -2762,7 +2763,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordMinimumLetters(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -2831,7 +2832,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordMinimumNumeric(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -2899,7 +2900,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordMinimumSymbols(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -2968,7 +2969,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordMinimumNonLetter(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -3120,7 +3121,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPasswordHistoryLength(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java index bdbce5282b94..ff7e181ba358 100644 --- a/core/java/android/app/assist/AssistContent.java +++ b/core/java/android/app/assist/AssistContent.java @@ -4,6 +4,7 @@ import android.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -14,18 +15,18 @@ import android.os.Parcelable; * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. */ public class AssistContent implements Parcelable { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mIsAppProvidedIntent = false; private boolean mIsAppProvidedWebUri = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private Intent mIntent; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mStructuredData; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private ClipData mClipData; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private Uri mUri; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Bundle mExtras; public AssistContent() { @@ -174,7 +175,7 @@ public class AssistContent implements Parcelable { mIsAppProvidedWebUri = in.readInt() == 1; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) void writeToParcelInternal(Parcel dest, int flags) { if (mIntent != null) { dest.writeInt(1); diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl index 19de19a820b1..f8c5a815a32e 100644 --- a/core/java/android/app/backup/IBackupManager.aidl +++ b/core/java/android/app/backup/IBackupManager.aidl @@ -180,13 +180,6 @@ interface IBackupManager { void setAutoRestore(boolean doAutoRestore); /** - * Indicate that any necessary one-time provisioning has occurred. - * - * <p>Callers must hold the android.permission.BACKUP permission to use this method. - */ - void setBackupProvisioned(boolean isProvisioned); - - /** * Report whether the backup mechanism is currently enabled. * * <p>Callers must hold the android.permission.BACKUP permission to use this method. diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java index bfc6df260e80..f804681cb3e9 100644 --- a/core/java/android/app/job/JobWorkItem.java +++ b/core/java/android/app/job/JobWorkItem.java @@ -21,6 +21,7 @@ import static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN; import android.annotation.BytesLong; import android.annotation.UnsupportedAppUsage; import android.content.Intent; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -30,15 +31,15 @@ import android.os.Parcelable; * {@link JobParameters#dequeueWork() JobParameters.dequeueWork} for more details. */ final public class JobWorkItem implements Parcelable { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final Intent mIntent; final long mNetworkDownloadBytes; final long mNetworkUploadBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mDeliveryCount; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mWorkId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) Object mGrants; /** @@ -224,7 +225,7 @@ final public class JobWorkItem implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) JobWorkItem(Parcel in) { if (in.readInt() != 0) { mIntent = Intent.CREATOR.createFromParcel(in); diff --git a/core/java/android/app/usage/ConfigurationStats.java b/core/java/android/app/usage/ConfigurationStats.java index dff9b611010f..87a737db09b2 100644 --- a/core/java/android/app/usage/ConfigurationStats.java +++ b/core/java/android/app/usage/ConfigurationStats.java @@ -17,6 +17,7 @@ package android.app.usage; import android.annotation.UnsupportedAppUsage; import android.content.res.Configuration; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -29,37 +30,37 @@ public final class ConfigurationStats implements Parcelable { /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public Configuration mConfiguration; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mBeginTimeStamp; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mEndTimeStamp; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mLastTimeActive; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mTotalTimeActive; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int mActivationCount; /** diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index a06213d77a68..d7a53281bc56 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -19,6 +19,7 @@ import android.annotation.IntDef; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.content.res.Configuration; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -268,13 +269,13 @@ public final class UsageEvents implements Parcelable { /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String mPackage; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String mClass; @@ -286,20 +287,20 @@ public final class UsageEvents implements Parcelable { /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mTimeStamp; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int mEventType; /** * Only present for {@link #CONFIGURATION_CHANGE} event types. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public Configuration mConfiguration; /** @@ -501,30 +502,30 @@ public final class UsageEvents implements Parcelable { } // Only used when creating the resulting events. Not used for reading/unparceling. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private List<Event> mEventsToWrite = null; // Only used for reading/unparceling events. @UnsupportedAppUsage private Parcel mParcel = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final int mEventCount; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mIndex = 0; /* * In order to save space, since ComponentNames will be duplicated everywhere, * we use a map and index into it. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String[] mStringPool; /** * Construct the iterator from a parcel. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public UsageEvents(Parcel in) { byte[] bytes = in.readBlob(); Parcel data = Parcel.obtain(); @@ -609,7 +610,7 @@ public final class UsageEvents implements Parcelable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int findStringIndex(String str) { final int index = Arrays.binarySearch(mStringPool, str); if (index < 0) { @@ -621,7 +622,7 @@ public final class UsageEvents implements Parcelable { /** * Writes a single event to the parcel. Modify this when updating {@link Event}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private void writeEventToParcel(Event event, Parcel p, int flags) { final int packageIndex; if (event.mPackage != null) { @@ -666,7 +667,7 @@ public final class UsageEvents implements Parcelable { /** * Reads a single event from the parcel. Modify this when updating {@link Event}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private void readEventFromParcel(Parcel p, Event eventOut) { final int packageIndex = p.readInt(); if (packageIndex >= 0) { diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java index 8fb7f4cb4d99..308180badbb8 100644 --- a/core/java/android/app/usage/UsageStats.java +++ b/core/java/android/app/usage/UsageStats.java @@ -29,6 +29,7 @@ import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -44,19 +45,19 @@ public final class UsageStats implements Parcelable { /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String mPackageName; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mBeginTimeStamp; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mEndTimeStamp; /** @@ -64,7 +65,7 @@ public final class UsageStats implements Parcelable { * {@link android.app.usage.UsageEvents.Event#ACTIVITY_RESUMED} event. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long mLastTimeUsed; /** diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 3f348033a8aa..26beb45be13f 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -233,7 +233,7 @@ public final class UsageStatsManager { @SystemApi public static final String EXTRA_TIME_USED = "android.app.usage.extra.TIME_USED"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static final UsageEvents sEmptyResults = new UsageEvents(); @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 466b9cee10a0..171c2f5b1a08 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -878,7 +878,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static String stateToString(int state) { switch (state) { case STATE_DISCONNECTED: diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java index 3a78cbdd4d0a..1edbacbae4f7 100755 --- a/core/java/android/bluetooth/BluetoothClass.java +++ b/core/java/android/bluetooth/BluetoothClass.java @@ -18,6 +18,7 @@ package android.bluetooth; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -65,7 +66,7 @@ public final class BluetoothClass implements Parcelable { private final int mClass; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public BluetoothClass(int classInt) { mClass = classInt; } diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java index fdbfec00e627..bc3c9a9ebf4b 100644 --- a/core/java/android/bluetooth/BluetoothUuid.java +++ b/core/java/android/bluetooth/BluetoothUuid.java @@ -17,6 +17,7 @@ package android.bluetooth; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.ParcelUuid; import java.nio.ByteBuffer; @@ -38,20 +39,20 @@ public final class BluetoothUuid { * The following 128 bit values are calculated as: * uuid * 2^96 + BASE_UUID */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final ParcelUuid AudioSink = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"); public static final ParcelUuid AudioSource = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB"); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final ParcelUuid AdvAudioDist = ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB"); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final ParcelUuid HSP = ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB"); public static final ParcelUuid HSP_AG = ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB"); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final ParcelUuid Handsfree = ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB"); public static final ParcelUuid Handsfree_AG = diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 001e328fb0ba..125c4c6b6503 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -49,6 +49,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.net.NetworkStack; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -691,7 +692,8 @@ public abstract class Context { * * @see android.content.res.Resources.Theme#obtainStyledAttributes(int[]) */ - public final TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) { + @NonNull + public final TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[] attrs) { return getTheme().obtainStyledAttributes(attrs); } @@ -702,8 +704,9 @@ public abstract class Context { * * @see android.content.res.Resources.Theme#obtainStyledAttributes(int, int[]) */ - public final TypedArray obtainStyledAttributes( - @StyleRes int resid, @StyleableRes int[] attrs) throws Resources.NotFoundException { + @NonNull + public final TypedArray obtainStyledAttributes(@StyleRes int resid, + @NonNull @StyleableRes int[] attrs) throws Resources.NotFoundException { return getTheme().obtainStyledAttributes(resid, attrs); } @@ -714,8 +717,9 @@ public abstract class Context { * * @see android.content.res.Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int) */ + @NonNull public final TypedArray obtainStyledAttributes( - AttributeSet set, @StyleableRes int[] attrs) { + @Nullable AttributeSet set, @NonNull @StyleableRes int[] attrs) { return getTheme().obtainStyledAttributes(set, attrs, 0, 0); } @@ -726,8 +730,9 @@ public abstract class Context { * * @see android.content.res.Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int) */ - public final TypedArray obtainStyledAttributes( - AttributeSet set, @StyleableRes int[] attrs, @AttrRes int defStyleAttr, + @NonNull + public final TypedArray obtainStyledAttributes(@Nullable AttributeSet set, + @NonNull @StyleableRes int[] attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { return getTheme().obtainStyledAttributes( set, attrs, defStyleAttr, defStyleRes); @@ -3118,6 +3123,7 @@ public abstract class Context { APPWIDGET_SERVICE, //@hide: VOICE_INTERACTION_MANAGER_SERVICE, //@hide: BACKUP_SERVICE, + ROLLBACK_SERVICE, DROPBOX_SERVICE, //@hide: DEVICE_IDLE_CONTROLLER, DEVICE_POLICY_SERVICE, @@ -3615,6 +3621,15 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve a + * {@link NetworkStack} for communicating with the network stack + * @hide + * @see #getSystemService(String) + * @see NetworkStack + */ + public static final String NETWORK_STACK_SERVICE = "network_stack"; + + /** + * Use with {@link #getSystemService(String)} to retrieve a * {@link android.net.IpSecManager} for encrypting Sockets or Networks with * IPSec. * @@ -3989,6 +4004,17 @@ public abstract class Context { public static final String BACKUP_SERVICE = "backup"; /** + * Use with {@link #getSystemService(String)} to retrieve an + * {@link android.content.rollback.RollbackManager} for communicating + * with the rollback manager + * + * @see #getSystemService(String) + * @hide TODO(ruhler): hidden, @TestApi until we decide on public vs. @SystemApi. + */ + @TestApi + public static final String ROLLBACK_SERVICE = "rollback"; + + /** * Use with {@link #getSystemService(String)} to retrieve a * {@link android.os.DropBoxManager} instance for recording * diagnostic logs. diff --git a/core/java/android/content/Entity.java b/core/java/android/content/Entity.java index b9473e04c63c..ff4f15006280 100644 --- a/core/java/android/content/Entity.java +++ b/core/java/android/content/Entity.java @@ -18,6 +18,7 @@ package android.content; import android.annotation.UnsupportedAppUsage; import android.net.Uri; +import android.os.Build; import java.util.ArrayList; @@ -29,9 +30,9 @@ import java.util.ArrayList; * corresponds to that RawContact. The uri refers to the Data table uri for each row. */ public final class Entity { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final private ContentValues mValues; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final private ArrayList<NamedContentValues> mSubValues; public Entity(ContentValues values) { diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index d5c6c63243f6..34922000e3cf 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -27,6 +27,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; @@ -2248,6 +2249,32 @@ public class Intent implements Parcelable, Cloneable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; /** + * Broadcast Action: Sent to the system rollback manager when a package + * needs to have rollback enabled. + * <p class="note"> + * This is a protected intent that can only be sent by the system. + * </p> + * + * @hide This broadcast is used internally by the system. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGE_ENABLE_ROLLBACK = + "android.intent.action.PACKAGE_ENABLE_ROLLBACK"; + /** + * Broadcast Action: An existing version of an application package has been + * rolled back to a previous version. + * The data contains the name of the package. + * + * <p class="note">This is a protected intent that can only be sent + * by the system. + * + * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi. + */ + @TestApi + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGE_ROLLBACK_EXECUTED = + "android.intent.action.PACKAGE_ROLLBACK_EXECUTED"; + /** * @hide * Broadcast Action: Ask system services if there is any reason to * restart the given package. The data contains the name of the @@ -9142,7 +9169,7 @@ public class Intent implements Parcelable, Cloneable { * @param extras The new set of extras in the Intent, or null to erase * all extras. */ - public @NonNull Intent replaceExtras(@NonNull Bundle extras) { + public @NonNull Intent replaceExtras(@Nullable Bundle extras) { mExtras = extras != null ? new Bundle(extras) : null; return this; } @@ -10343,6 +10370,7 @@ public class Intent implements Parcelable, Cloneable { case ACTION_MEDIA_SCANNER_SCAN_FILE: case ACTION_PACKAGE_NEEDS_VERIFICATION: case ACTION_PACKAGE_VERIFIED: + case ACTION_PACKAGE_ENABLE_ROLLBACK: // Ignore legacy actions break; default: diff --git a/core/java/android/content/SyncAdapterType.java b/core/java/android/content/SyncAdapterType.java index ff77676505a7..6cd4841b9cf0 100644 --- a/core/java/android/content/SyncAdapterType.java +++ b/core/java/android/content/SyncAdapterType.java @@ -18,6 +18,7 @@ package android.content; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.text.TextUtils; import android.os.Parcelable; import android.os.Parcel; @@ -30,9 +31,9 @@ public class SyncAdapterType implements Parcelable { public final String authority; public final String accountType; public final boolean isKey; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final boolean userVisible; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final boolean supportsUploading; @UnsupportedAppUsage private final boolean isAlwaysSyncable; @@ -85,7 +86,7 @@ public class SyncAdapterType implements Parcelable { this.packageName = packageName; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private SyncAdapterType(String authority, String accountType) { if (TextUtils.isEmpty(authority)) { throw new IllegalArgumentException("the authority must not be empty: " + authority); diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java index 7ebf922aead0..403cbcbf8b2f 100644 --- a/core/java/android/content/SyncInfo.java +++ b/core/java/android/content/SyncInfo.java @@ -18,6 +18,7 @@ package android.content; import android.accounts.Account; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -95,7 +96,7 @@ public class SyncInfo implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) SyncInfo(Parcel parcel) { authorityId = parcel.readInt(); account = parcel.readParcelable(Account.class.getClassLoader()); diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index 07b23d1decc0..dd550032df7c 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -19,6 +19,7 @@ package android.content.om; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -114,7 +115,7 @@ public final class OverlayInfo implements Parcelable { /** * Package name of the target package */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public final String targetPackageName; /** diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 0c438afd7a83..2978058b2848 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; @@ -638,6 +639,21 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_HAS_FRAGILE_USER_DATA = 1 << 24; + /** + * Indicate whether this application prefers code integrity, that is, run only code that is + * signed. This requires android:extractNativeLibs to be "false", as well as .dex and .so (if + * any) stored uncompressed inside the APK, which is signed. At run time, the implications + * include: + * + * <ul> + * <li>ART will JIT the dex code directly from the APK. There may be performance characteristic + * changes depend on the actual workload. + * </ul> + * + * @hide + */ + public static final int PRIVATE_FLAG_PREFER_CODE_INTEGRITY = 1 << 25; + /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, @@ -653,6 +669,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, PRIVATE_FLAG_OEM, PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, + PRIVATE_FLAG_PREFER_CODE_INTEGRITY, PRIVATE_FLAG_PRIVILEGED, PRIVATE_FLAG_PRODUCT, PRIVATE_FLAG_PRODUCT_SERVICES, @@ -1449,9 +1466,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return sCollator.compare(sa.toString(), sb.toString()); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Collator sCollator = Collator.getInstance(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private PackageManager mPM; } @@ -1693,7 +1710,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void disableCompatibilityMode() { flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS | @@ -1829,7 +1846,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return pm.getDefaultActivityIcon(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean isPackageUnavailable(PackageManager pm) { try { return pm.getPackageInfo(packageName, 0) == null; diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index a4ea513a055f..64a4479be7ee 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -277,7 +277,7 @@ interface IPackageManager { in PersistableBundle appExtras, in PersistableBundle launcherExtras, in SuspendDialogInfo dialogInfo, String callingPackage, int userId); - boolean canSuspendPackageForUser(String packageName, int userId); + String[] getUnsuspendablePackagesForUser(in String[] packageNames, int userId); boolean isPackageSuspendedForUser(String packageName, int userId); diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 099d15ad61c2..b8d7889c86ff 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -19,6 +19,7 @@ package android.content.pm; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.apex.ApexInfo; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -514,7 +515,7 @@ public class PackageInfo implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private PackageInfo(Parcel source) { packageName = source.readString(); splitNames = source.createStringArray(); diff --git a/core/java/android/content/pm/PackageInfoLite.java b/core/java/android/content/pm/PackageInfoLite.java index e0e67b9321aa..b878a955c223 100644 --- a/core/java/android/content/pm/PackageInfoLite.java +++ b/core/java/android/content/pm/PackageInfoLite.java @@ -17,6 +17,7 @@ package android.content.pm; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -116,7 +117,7 @@ public class PackageInfoLite implements Parcelable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final Parcelable.Creator<PackageInfoLite> CREATOR = new Parcelable.Creator<PackageInfoLite>() { public PackageInfoLite createFromParcel(Parcel source) { diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 623bdda93b7e..a2fd83f9d8a0 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -24,6 +24,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.AppGlobals; @@ -145,6 +146,15 @@ public class PackageInstaller { public static final String ACTION_SESSION_COMMITTED = "android.content.pm.action.SESSION_COMMITTED"; + /** + * Broadcast Action: Send information about a staged install session when its state is updated. + * <p> + * The associated session information is defined in {@link #EXTRA_SESSION}. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_SESSION_UPDATED = + "android.content.pm.action.SESSION_UPDATED"; + /** {@hide} */ public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL"; @@ -1416,6 +1426,15 @@ public class PackageInstaller { this.grantedRuntimePermissions = permissions; } + /** + * Request that rollbacks be enabled for the given upgrade. + * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi. + */ + @TestApi + public void setEnableRollback() { + installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK; + } + /** {@hide} */ @SystemApi public void setAllowDowngrade(boolean allowDowngrade) { diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 9d604bbd75aa..611055759868 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -720,6 +720,9 @@ public abstract class PackageManager { INSTALL_FORCE_SDK, INSTALL_FULL_APP, INSTALL_ALLOCATE_AGGRESSIVE, + INSTALL_VIRTUAL_PRELOAD, + INSTALL_APEX, + INSTALL_ENABLE_ROLLBACK, }) @Retention(RetentionPolicy.SOURCE) public @interface InstallFlags {} @@ -857,6 +860,14 @@ public abstract class PackageManager { */ public static final int INSTALL_APEX = 0x00020000; + /** + * Flag parameter for {@link #installPackage} to indicate that rollback + * should be enabled for this install. + * + * @hide + */ + public static final int INSTALL_ENABLE_ROLLBACK = 0x00040000; + /** @hide */ @IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = { DONT_KILL_APP @@ -5958,27 +5969,28 @@ public abstract class PackageManager { } /** - * Returns whether or not a given package can be suspended via a call to {@link + * Returns any packages in a given set of packages that cannot be suspended via a call to {@link * #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle, * SuspendDialogInfo) setPackagesSuspended}. The platform prevents suspending certain critical * packages to keep the device in a functioning state, e.g. the default dialer. * Apps need to hold {@link Manifest.permission#SUSPEND_APPS SUSPEND_APPS} to call this api. * * <p> - * Note that this set of critical packages can change with time, so <em>a value of {@code true} - * returned by this api does not guarantee that a following call to {@link - * #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle, - * SuspendDialogInfo) setPackagesSuspended} for the same package will succeed</em>, especially - * if considerable time elapsed between the two calls. + * Note that this set of critical packages can change with time, so even though a package name + * was not returned by this call, it does not guarantee that a subsequent call to + * {@link #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle, + * SuspendDialogInfo) setPackagesSuspended} for that package will succeed, especially if + * significant time elapsed between the two calls. * - * @param packageName The package to check. - * @return {@code true} if the given package can be suspended, {@code false} otherwise. + * @param packageNames The packages to check. + * @return A list of packages that can not be currently suspended by the system. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.SUSPEND_APPS) - public boolean canSuspendPackage(@NonNull String packageName) { - throw new UnsupportedOperationException("canSuspendPackage not implemented"); + @NonNull + public String[] getUnsuspendablePackages(@NonNull String[] packageNames) { + throw new UnsupportedOperationException("canSuspendPackages not implemented"); } /** diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 5db9f506e6e4..83979e925be1 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -759,4 +759,48 @@ public abstract class PackageManagerInternal { /** Returns whether the given package is enabled for the given user */ public abstract @PackageManager.EnabledState int getApplicationEnabledState( String packageName, int userId); + + /** + * Extra field name for the token of a request to enable rollback for a + * package. + */ + public static final String EXTRA_ENABLE_ROLLBACK_TOKEN = + "android.content.pm.extra.ENABLE_ROLLBACK_TOKEN"; + + /** + * Extra field name for the installFlags of a request to enable rollback + * for a package. + */ + public static final String EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS = + "android.content.pm.extra.ENABLE_ROLLBACK_INSTALL_FLAGS"; + + /** + * Used as the {@code enableRollbackCode} argument for + * {@link PackageManagerInternal#setEnableRollbackCode} to indicate that + * enabling rollback succeeded. + */ + public static final int ENABLE_ROLLBACK_SUCCEEDED = 1; + + /** + * Used as the {@code enableRollbackCode} argument for + * {@link PackageManagerInternal#setEnableRollbackCode} to indicate that + * enabling rollback failed. + */ + public static final int ENABLE_ROLLBACK_FAILED = -1; + + /** + * Allows the rollback manager listening to the + * {@link Intent#ACTION_PACKAGE_ENABLE_ROLLBACK enable rollback broadcast} + * to respond to the package manager. The response must include the + * {@code enableRollbackCode} which is one of + * {@link PackageManager#ENABLE_ROLLBACK_SUCCEEDED} or + * {@link PackageManager#ENABLE_ROLLBACK_FAILED}. + * + * @param token pending package identifier as passed via the + * {@link PackageManager#EXTRA_ENABLE_ROLLBACK_TOKEN} Intent extra. + * @param enableRollbackCode the status code result of enabling rollback + * @throws SecurityException if the caller does not have the + * PACKAGE_ROLLBACK_AGENT permission. + */ + public abstract void setEnableRollbackCode(int token, int enableRollbackCode); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index e38b294b4485..2b266b730485 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -475,6 +475,7 @@ public class PackageParser { public final boolean extractNativeLibs; public final boolean isolatedSplits; public final boolean isSplitRequired; + public final boolean preferCodeIntegrity; public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit, @@ -483,7 +484,7 @@ public class PackageParser { int revisionCode, int installLocation, List<VerifierInfo> verifiers, SigningDetails signingDetails, boolean coreApp, boolean debuggable, boolean multiArch, boolean use32bitAbi, - boolean extractNativeLibs, boolean isolatedSplits) { + boolean preferCodeIntegrity, boolean extractNativeLibs, boolean isolatedSplits) { this.codePath = codePath; this.packageName = packageName; this.splitName = splitName; @@ -500,6 +501,7 @@ public class PackageParser { this.debuggable = debuggable; this.multiArch = multiArch; this.use32bitAbi = use32bitAbi; + this.preferCodeIntegrity = preferCodeIntegrity; this.extractNativeLibs = extractNativeLibs; this.isolatedSplits = isolatedSplits; this.isSplitRequired = isSplitRequired; @@ -1722,6 +1724,7 @@ public class PackageParser { boolean isolatedSplits = false; boolean isFeatureSplit = false; boolean isSplitRequired = false; + boolean preferCodeIntegrity = false; String configForSplit = null; String usesSplitName = null; @@ -1784,6 +1787,9 @@ public class PackageParser { if ("extractNativeLibs".equals(attr)) { extractNativeLibs = attrs.getAttributeBooleanValue(i, true); } + if ("preferCodeIntegrity".equals(attr)) { + preferCodeIntegrity = attrs.getAttributeBooleanValue(i, false); + } } } else if (TAG_USES_SPLIT.equals(parser.getName())) { if (usesSplitName != null) { @@ -1800,10 +1806,16 @@ public class PackageParser { } } + if (preferCodeIntegrity && extractNativeLibs) { + throw new PackageParserException( + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, + "Can't request both preferCodeIntegrity and extractNativeLibs"); + } + return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable, - multiArch, use32bitAbi, extractNativeLibs, isolatedSplits); + multiArch, use32bitAbi, preferCodeIntegrity, extractNativeLibs, isolatedSplits); } /** @@ -3655,6 +3667,12 @@ public class PackageParser { } if (sa.getBoolean( + R.styleable.AndroidManifestApplication_preferCodeIntegrity, + false)) { + ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY; + } + + if (sa.getBoolean( R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage, false)) { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java index f70ec390e90e..d3e86a35170e 100644 --- a/core/java/android/content/pm/PackageStats.java +++ b/core/java/android/content/pm/PackageStats.java @@ -18,6 +18,7 @@ package android.content.pm; import android.annotation.UnsupportedAppUsage; import android.app.usage.StorageStatsManager; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; @@ -38,7 +39,7 @@ public class PackageStats implements Parcelable { public String packageName; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int userHandle; /** Size of the code (e.g., APK) */ diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 1ca7b132fdab..7d101b8f78e5 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -612,7 +612,7 @@ public class CompatibilityInfo implements Parcelable { dest.writeFloat(applicationInvertedScale); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final Parcelable.Creator<CompatibilityInfo> CREATOR = new Parcelable.Creator<CompatibilityInfo>() { @Override diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 88b1c8803713..365ceac68ee1 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1468,7 +1468,8 @@ public class Resources { * @see #obtainStyledAttributes(int, int[]) * @see #obtainStyledAttributes(AttributeSet, int[], int, int) */ - public TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) { + @NonNull + public TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[] attrs) { return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, 0); } @@ -1493,7 +1494,9 @@ public class Resources { * @see #obtainStyledAttributes(int[]) * @see #obtainStyledAttributes(AttributeSet, int[], int, int) */ - public TypedArray obtainStyledAttributes(@StyleRes int resId, @StyleableRes int[] attrs) + @NonNull + public TypedArray obtainStyledAttributes(@StyleRes int resId, + @NonNull @StyleableRes int[] attrs) throws NotFoundException { return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, resId); } @@ -1547,8 +1550,10 @@ public class Resources { * @see #obtainStyledAttributes(int[]) * @see #obtainStyledAttributes(int, int[]) */ - public TypedArray obtainStyledAttributes(AttributeSet set, - @StyleableRes int[] attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + @NonNull + public TypedArray obtainStyledAttributes(@Nullable AttributeSet set, + @NonNull @StyleableRes int[] attrs, @AttrRes int defStyleAttr, + @StyleRes int defStyleRes) { return mThemeImpl.obtainStyledAttributes(this, set, attrs, defStyleAttr, defStyleRes); } diff --git a/core/java/android/content/rollback/IRollbackManager.aidl b/core/java/android/content/rollback/IRollbackManager.aidl new file mode 100644 index 000000000000..7f557cd8bbe8 --- /dev/null +++ b/core/java/android/content/rollback/IRollbackManager.aidl @@ -0,0 +1,41 @@ +/** + * 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 android.content.rollback; + +import android.content.pm.ParceledListSlice; +import android.content.pm.StringParceledListSlice; +import android.content.rollback.RollbackInfo; +import android.content.IntentSender; + +/** {@hide} */ +interface IRollbackManager { + + RollbackInfo getAvailableRollback(String packageName); + + StringParceledListSlice getPackagesWithAvailableRollbacks(); + + ParceledListSlice getRecentlyExecutedRollbacks(); + + void executeRollback(in RollbackInfo rollback, String callerPackageName, + in IntentSender statusReceiver); + + // Exposed for test purposes only. + void reloadPersistedData(); + + // Exposed for test purposes only. + void expireRollbackForPackage(String packageName); +} diff --git a/core/java/android/content/rollback/PackageRollbackInfo.aidl b/core/java/android/content/rollback/PackageRollbackInfo.aidl new file mode 100644 index 000000000000..9cb52c982754 --- /dev/null +++ b/core/java/android/content/rollback/PackageRollbackInfo.aidl @@ -0,0 +1,18 @@ +/* + * 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 android.content.rollback; + +parcelable PackageRollbackInfo; diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java new file mode 100644 index 000000000000..0c057656d59a --- /dev/null +++ b/core/java/android/content/rollback/PackageRollbackInfo.java @@ -0,0 +1,109 @@ +/* + * 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 android.content.rollback; + +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * Information about a rollback available for a particular package. + * + * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi. + */ +@TestApi +public final class PackageRollbackInfo implements Parcelable { + /** + * The name of a package being rolled back. + */ + public final String packageName; + + /** + * The version the package was rolled back from. + */ + public final PackageVersion higherVersion; + + /** + * The version the package was rolled back to. + */ + public final PackageVersion lowerVersion; + + /** + * Represents a version of a package. + */ + public static class PackageVersion { + public final long versionCode; + + // TODO(b/120200473): Include apk sha or some other way to distinguish + // between two different apks with the same version code. + public PackageVersion(long versionCode) { + this.versionCode = versionCode; + } + + @Override + public boolean equals(Object other) { + if (other instanceof PackageVersion) { + PackageVersion otherVersion = (PackageVersion) other; + return versionCode == otherVersion.versionCode; + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(versionCode); + } + } + + public PackageRollbackInfo(String packageName, + PackageVersion higherVersion, PackageVersion lowerVersion) { + this.packageName = packageName; + this.higherVersion = higherVersion; + this.lowerVersion = lowerVersion; + } + + private PackageRollbackInfo(Parcel in) { + this.packageName = in.readString(); + this.higherVersion = new PackageVersion(in.readLong()); + this.lowerVersion = new PackageVersion(in.readLong()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(packageName); + out.writeLong(higherVersion.versionCode); + out.writeLong(lowerVersion.versionCode); + } + + public static final Parcelable.Creator<PackageRollbackInfo> CREATOR = + new Parcelable.Creator<PackageRollbackInfo>() { + public PackageRollbackInfo createFromParcel(Parcel in) { + return new PackageRollbackInfo(in); + } + + public PackageRollbackInfo[] newArray(int size) { + return new PackageRollbackInfo[size]; + } + }; +} diff --git a/core/java/android/content/rollback/RollbackInfo.aidl b/core/java/android/content/rollback/RollbackInfo.aidl new file mode 100644 index 000000000000..a9dc5cd59cbb --- /dev/null +++ b/core/java/android/content/rollback/RollbackInfo.aidl @@ -0,0 +1,18 @@ +/* + * 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 android.content.rollback; + +parcelable RollbackInfo; diff --git a/core/java/android/content/rollback/RollbackInfo.java b/core/java/android/content/rollback/RollbackInfo.java new file mode 100644 index 000000000000..5fa4e57e78e5 --- /dev/null +++ b/core/java/android/content/rollback/RollbackInfo.java @@ -0,0 +1,70 @@ +/* + * 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 android.content.rollback; + +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Information about a set of packages that can be, or already have been + * rolled back together. + * + * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi. + */ +@TestApi +public final class RollbackInfo implements Parcelable { + + /** + * The package that needs to be rolled back. + */ + public final PackageRollbackInfo targetPackage; + + // TODO: Add a list of additional packages rolled back due to atomic + // install dependencies when rollback of atomic installs is supported. + // TODO: Add a flag to indicate if reboot is required, when rollback of + // staged installs is supported. + + public RollbackInfo(PackageRollbackInfo targetPackage) { + this.targetPackage = targetPackage; + } + + private RollbackInfo(Parcel in) { + this.targetPackage = PackageRollbackInfo.CREATOR.createFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + targetPackage.writeToParcel(out, flags); + } + + public static final Parcelable.Creator<RollbackInfo> CREATOR = + new Parcelable.Creator<RollbackInfo>() { + public RollbackInfo createFromParcel(Parcel in) { + return new RollbackInfo(in); + } + + public RollbackInfo[] newArray(int size) { + return new RollbackInfo[size]; + } + }; +} diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java new file mode 100644 index 000000000000..294151aff82c --- /dev/null +++ b/core/java/android/content/rollback/RollbackManager.java @@ -0,0 +1,174 @@ +/* + * 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 android.content.rollback; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemService; +import android.annotation.TestApi; +import android.content.Context; +import android.content.IntentSender; +import android.os.RemoteException; + +import java.util.List; + +/** + * Offers the ability to rollback packages after upgrade. + * <p> + * For packages installed with rollbacks enabled, the RollbackManager can be + * used to initiate rollback of those packages for a limited time period after + * upgrade. + * + * TODO: Require an appropriate permission for apps to use these APIs. + * + * @see PackageInstaller.SessionParams#setEnableRollback() + * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi. + */ +@TestApi +@SystemService(Context.ROLLBACK_SERVICE) +public final class RollbackManager { + private final String mCallerPackageName; + private final IRollbackManager mBinder; + + /** {@hide} */ + public RollbackManager(Context context, IRollbackManager binder) { + mCallerPackageName = context.getPackageName(); + mBinder = binder; + } + + /** + * Returns the rollback currently available to be executed for the given + * package. + * <p> + * The returned RollbackInfo describes what packages would be rolled back, + * including package version codes before and after rollback. The rollback + * can be initiated using {@link #executeRollback(RollbackInfo,IntentSender)}. + * <p> + * TODO: What if there is no package installed on device for packageName? + * + * @param packageName name of the package to get the availble RollbackInfo for. + * @return the rollback available for the package, or null if no rollback + * is available for the package. + */ + public @Nullable RollbackInfo getAvailableRollback(@NonNull String packageName) { + try { + return mBinder.getAvailableRollback(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Gets the names of packages that are available for rollback. + * Call {@link #getAvailableRollback(String)} to get more information + * about the rollback available for a particular package. + * + * @return the names of packages that are available for rollback. + */ + public @NonNull List<String> getPackagesWithAvailableRollbacks() { + try { + return mBinder.getPackagesWithAvailableRollbacks().getList(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + + /** + * Gets the list of all recently executed rollbacks. + * This is for the purposes of preventing re-install of a bad version of a + * package. + * <p> + * Returns an empty list if there are no recently executed rollbacks. + * <p> + * To avoid having to keep around complete rollback history forever on a + * device, the returned list of rollbacks is only guaranteed to include + * rollbacks that are still relevant. A rollback is no longer considered + * relevant if the package is subsequently uninstalled or upgraded + * (without the possibility of rollback) to a higher version code than was + * rolled back from. + * + * @return the recently executed rollbacks + */ + public @NonNull List<RollbackInfo> getRecentlyExecutedRollbacks() { + try { + return mBinder.getRecentlyExecutedRollbacks().getList(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Execute the given rollback, rolling back all versions of the packages + * to the last good versions previously installed on the device as + * specified in the given rollback object. The rollback will fail if any + * of the installed packages or available rollbacks are inconsistent with + * the versions specified in the given rollback object, which can happen + * if a package has been updated or a rollback expired since the rollback + * object was retrieved from {@link #getAvailableRollback(String)}. + * <p> + * TODO: Specify the returns status codes. + * TODO: What happens in case reboot is required for the rollback to take + * effect for staged installs? + * + * @param rollback to execute + * @param statusReceiver where to deliver the results + */ + public void executeRollback(@NonNull RollbackInfo rollback, + @NonNull IntentSender statusReceiver) { + try { + mBinder.executeRollback(rollback, mCallerPackageName, statusReceiver); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Reload all persisted rollback data from device storage. + * This API is meant to test that rollback state is properly preserved + * across device reboot, by simulating what happens on reboot without + * actually rebooting the device. + * + * @hide + */ + @TestApi + public void reloadPersistedData() { + try { + mBinder.reloadPersistedData(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Expire the rollback data for a given package. + * This API is meant to facilitate testing of rollback logic for + * expiring rollback data. + * + * @param packageName the name of the package to expire data for. + * + * @hide + */ + @TestApi + public void expireRollbackForPackage(@NonNull String packageName) { + try { + mBinder.expireRollbackForPackage(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } +} diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java index f78b484e0491..992da312201d 100644 --- a/core/java/android/database/DatabaseUtils.java +++ b/core/java/android/database/DatabaseUtils.java @@ -30,6 +30,7 @@ import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteFullException; import android.database.sqlite.SQLiteProgram; import android.database.sqlite.SQLiteStatement; +import android.os.Build; import android.os.OperationCanceledException; import android.os.Parcel; import android.os.ParcelFileDescriptor; @@ -322,7 +323,7 @@ public class DatabaseUtils { * @return object value type * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static int getTypeOfObject(Object obj) { if (obj == null) { return Cursor.FIELD_TYPE_NULL; diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java index 5033296df9fb..a52e96e249f8 100644 --- a/core/java/android/database/MatrixCursor.java +++ b/core/java/android/database/MatrixCursor.java @@ -17,6 +17,7 @@ package android.database; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import java.util.ArrayList; /** @@ -27,9 +28,9 @@ import java.util.ArrayList; public class MatrixCursor extends AbstractCursor { private final String[] columnNames; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private Object[] data; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int rowCount = 0; private final int columnCount; diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java index 4fce2d7fe0df..5722e7b25fbf 100644 --- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java +++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java @@ -53,11 +53,11 @@ public class SQLiteQueryBuilder { private Map<String, String> mProjectionMap = null; private List<Pattern> mProjectionGreylist = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mTables = ""; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private StringBuilder mWhereClause = null; // lazily created - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mDistinct; private SQLiteDatabase.CursorFactory mFactory; private boolean mStrict; @@ -800,7 +800,7 @@ public class SQLiteQueryBuilder { return query.toString(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String[] computeProjection(String[] projectionIn) { if (projectionIn != null && projectionIn.length > 0) { if (mProjectionMap != null) { diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java index a4c1332b45d1..dd782ec3a42f 100644 --- a/core/java/android/hardware/display/ColorDisplayManager.java +++ b/core/java/android/hardware/display/ColorDisplayManager.java @@ -60,6 +60,13 @@ public final class ColorDisplayManager { return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable); } + /** + * Returns {@code true} if display white balance is supported by the device. + */ + public static boolean isDisplayWhiteBalanceAvailable(Context context) { + return context.getResources().getBoolean(R.bool.config_displayWhiteBalanceAvailable); + } + private static class ColorDisplayManagerInternal { private static ColorDisplayManagerInternal sInstance; diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index bac23b3c00f9..1630b0603f3a 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -975,14 +975,11 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan mAuthenticationCallback.onAuthenticationAcquired(acquireInfo); } final String msg = getAcquiredString(mContext, acquireInfo, vendorCode); - if (msg == null) { - return; - } final int clientInfo = acquireInfo == FACE_ACQUIRED_VENDOR ? (vendorCode + FACE_ACQUIRED_VENDOR_BASE) : acquireInfo; if (mEnrollmentCallback != null) { mEnrollmentCallback.onEnrollmentHelp(clientInfo, msg); - } else if (mAuthenticationCallback != null) { + } else if (mAuthenticationCallback != null && msg != null) { mAuthenticationCallback.onAuthenticationHelp(clientInfo, msg); } } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 097a3e3a270a..7d40227f9c7d 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -41,6 +41,7 @@ import android.database.ContentObserver; import android.graphics.Rect; import android.graphics.Region; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -352,7 +353,7 @@ public class InputMethodService extends AbstractInputMethodService { InputMethodManager mImm; private InputMethodPrivilegedOperations mPrivOps = new InputMethodPrivilegedOperations(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mTheme = 0; LayoutInflater mInflater; @@ -410,7 +411,7 @@ public class InputMethodService extends AbstractInputMethodService { @GuardedBy("mLock") private boolean mNotifyUserActionSent; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final Insets mTmpInsets = new Insets(); final int[] mTmpLocation = new int[2]; diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 49c3dc63e151..61d5a9127743 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -27,6 +27,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Binder; +import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Handler; @@ -2768,7 +2769,7 @@ public class ConnectivityManager { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void unregisterNetworkFactory(Messenger messenger) { try { mService.unregisterNetworkFactory(messenger); diff --git a/core/java/android/net/INetworkStackConnector.aidl b/core/java/android/net/INetworkStackConnector.aidl new file mode 100644 index 000000000000..29f882858c05 --- /dev/null +++ b/core/java/android/net/INetworkStackConnector.aidl @@ -0,0 +1,21 @@ +/** + * 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 perNmissions and + * limitations under the License. + */ +package android.net; + +/** @hide */ +oneway interface INetworkStackConnector { + // TODO: requestDhcpServer(), etc. will go here +}
\ No newline at end of file diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java index 77562dbd7bfa..b40f15ae17ba 100644 --- a/core/java/android/net/LinkAddress.java +++ b/core/java/android/net/LinkAddress.java @@ -27,6 +27,7 @@ import static android.system.OsConstants.RT_SCOPE_UNIVERSE; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.Pair; @@ -56,13 +57,13 @@ public class LinkAddress implements Parcelable { /** * IPv4 or IPv6 address. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private InetAddress address; /** * Prefix length. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int prefixLength; /** diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 1b9a66cd6ea7..3a792065155e 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -18,7 +18,9 @@ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -49,7 +51,7 @@ import java.util.StringJoiner; */ public final class LinkProperties implements Parcelable { // The interface described by the network link. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mIfaceName; private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<>(); private ArrayList<InetAddress> mDnses = new ArrayList<>(); @@ -161,7 +163,7 @@ public final class LinkProperties implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @SystemApi public LinkProperties() { } @@ -195,7 +197,7 @@ public final class LinkProperties implements Parcelable { * @param iface The name of the network interface used for this link. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setInterfaceName(String iface) { mIfaceName = iface; ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size()); @@ -346,7 +348,7 @@ public final class LinkProperties implements Parcelable { * object. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setLinkAddresses(Collection<LinkAddress> addresses) { mLinkAddresses.clear(); for (LinkAddress address: addresses) { @@ -392,7 +394,7 @@ public final class LinkProperties implements Parcelable { * @param dnsServers The {@link Collection} of DNS servers to set in this object. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setDnsServers(Collection<InetAddress> dnsServers) { mDnses.clear(); for (InetAddress dnsServer: dnsServers) { @@ -529,7 +531,7 @@ public final class LinkProperties implements Parcelable { * domains to search when resolving host names on this link. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setDomains(String domains) { mDomains = domains; } @@ -552,7 +554,7 @@ public final class LinkProperties implements Parcelable { * @param mtu The MTU to use for this link. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setMtu(int mtu) { mMtu = mtu; } @@ -562,9 +564,7 @@ public final class LinkProperties implements Parcelable { * this will return 0. * * @return The mtu value set for this link. - * @hide */ - @UnsupportedAppUsage public int getMtu() { return mMtu; } @@ -613,7 +613,7 @@ public final class LinkProperties implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @SystemApi public boolean addRoute(RouteInfo route) { if (route != null) { String routeIface = route.getInterface(); @@ -688,7 +688,7 @@ public final class LinkProperties implements Parcelable { * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setHttpProxy(ProxyInfo proxy) { mHttpProxy = proxy; } @@ -760,7 +760,7 @@ public final class LinkProperties implements Parcelable { * Clears this object to its initial state. * @hide */ - @UnsupportedAppUsage + @SystemApi public void clear() { mIfaceName = null; mLinkAddresses.clear(); @@ -1137,7 +1137,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean isIdenticalHttpProxy(LinkProperties target) { return getHttpProxy() == null ? target.getHttpProxy() == null : getHttpProxy().equals(target.getHttpProxy()); diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 114b423c3184..99bfc140f140 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -19,6 +19,7 @@ package android.net; import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.ConnectivityManager.PacketKeepalive; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -352,7 +353,7 @@ public abstract class NetworkAgent extends Handler { /** * Called by the bearer code when it has new NetworkInfo data. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void sendNetworkInfo(NetworkInfo networkInfo) { queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo)); } diff --git a/core/java/android/net/NetworkBadging.java b/core/java/android/net/NetworkBadging.java index c119b637140f..cd9ea88e5b76 100644 --- a/core/java/android/net/NetworkBadging.java +++ b/core/java/android/net/NetworkBadging.java @@ -21,13 +21,10 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; import android.net.wifi.WifiManager; -import android.view.View; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -96,34 +93,4 @@ public class NetworkBadging { throw new IllegalArgumentException("Invalid signal level: " + signalLevel); } } - - /** - * Returns the badged wifi signal resource id for the given signal level. - * - * <p>This badged wifi signal resource should be displayed with the quality badge retrieved - * from {@link #getWifiBadgeResource(int)}. If there is no badge, - * {@link #getWifiBadgeResource(int)} should be used instead of this method. - * - * @param signalLevel The level returned by {@link WifiManager#calculateSignalLevel(int, int)} - * for a network. Must be between 0 and {@link WifiManager#RSSI_LEVELS}-1. - * @return the @DrawableRes for the icon - * @throws IllegalArgumentException for an invalid signal level - * @hide - */ - @DrawableRes private static int getBadgedWifiSignalResource(int signalLevel) { - switch (signalLevel) { - case 0: - return com.android.internal.R.drawable.ic_signal_wifi_badged_0_bars; - case 1: - return com.android.internal.R.drawable.ic_signal_wifi_badged_1_bar; - case 2: - return com.android.internal.R.drawable.ic_signal_wifi_badged_2_bars; - case 3: - return com.android.internal.R.drawable.ic_signal_wifi_badged_3_bars; - case 4: - return com.android.internal.R.drawable.ic_signal_wifi_badged_4_bars; - default: - throw new IllegalArgumentException("Invalid signal level: " + signalLevel); - } - } } diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index c41a56c7305f..1b44c920a205 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -1017,7 +1017,7 @@ public final class NetworkCapabilities implements Parcelable { * @return The bearer-specific signal strength. * @hide */ - @UnsupportedAppUsage + @SystemApi public int getSignalStrength() { return mSignalStrength; } diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java index 9c836c3382db..181cab41e928 100644 --- a/core/java/android/net/NetworkFactory.java +++ b/core/java/android/net/NetworkFactory.java @@ -18,6 +18,7 @@ package android.net; import android.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -289,7 +290,7 @@ public class NetworkFactory extends Handler { sendMessage(obtainMessage(CMD_CANCEL_REQUEST, networkRequest)); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setScoreFilter(int score) { sendMessage(obtainMessage(CMD_SET_SCORE, score, 0)); } @@ -307,7 +308,7 @@ public class NetworkFactory extends Handler { Log.d(LOG_TAG, s); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); pw.println(toString()); diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 299b23206dcf..5ab34e9aa6e8 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -28,6 +28,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; +import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; import android.util.DebugUtils; @@ -203,7 +204,7 @@ public class NetworkPolicyManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void registerListener(INetworkPolicyListener listener) { try { mService.registerListener(listener); @@ -212,7 +213,7 @@ public class NetworkPolicyManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void unregisterListener(INetworkPolicyListener listener) { try { mService.unregisterListener(listener); diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index 04b6b44013b9..9508217be53f 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -17,9 +17,11 @@ package android.net; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.net.NetworkCapabilities.NetCapability; import android.net.NetworkCapabilities.Transport; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; @@ -56,7 +58,7 @@ public class NetworkRequest implements Parcelable { * Causes CONNECTIVITY_ACTION broadcasts to be sent. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public final int legacyType; /** @@ -344,7 +346,7 @@ public class NetworkRequest implements Parcelable { * @param signalStrength the bearer-specific signal strength. * @hide */ - @UnsupportedAppUsage + @SystemApi public Builder setSignalStrength(int signalStrength) { mNetworkCapabilities.setSignalStrength(signalStrength); return this; diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java new file mode 100644 index 000000000000..82a4e31a81dd --- /dev/null +++ b/core/java/android/net/NetworkStack.java @@ -0,0 +1,156 @@ +/* + * 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 android.net; + +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemService; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Binder; +import android.os.IBinder; +import android.os.Process; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +/** + * Service used to communicate with the network stack, which is running in a separate module. + * @hide + */ +@SystemService(Context.NETWORK_STACK_SERVICE) +public class NetworkStack { + private static final String TAG = NetworkStack.class.getSimpleName(); + + @NonNull + @GuardedBy("mPendingNetStackRequests") + private final ArrayList<NetworkStackRequest> mPendingNetStackRequests = new ArrayList<>(); + @Nullable + @GuardedBy("mPendingNetStackRequests") + private INetworkStackConnector mConnector; + + private interface NetworkStackRequest { + void onNetworkStackConnected(INetworkStackConnector connector); + } + + public NetworkStack() { } + + private class NetworkStackConnection implements ServiceConnection { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + registerNetworkStackService(service); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + // TODO: crash/reboot the system ? + Slog.wtf(TAG, "Lost network stack connector"); + } + }; + + private void registerNetworkStackService(@NonNull IBinder service) { + final INetworkStackConnector connector = INetworkStackConnector.Stub.asInterface(service); + + ServiceManager.addService(Context.NETWORK_STACK_SERVICE, service, false /* allowIsolated */, + DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); + + final ArrayList<NetworkStackRequest> requests; + synchronized (mPendingNetStackRequests) { + requests = new ArrayList<>(mPendingNetStackRequests); + mPendingNetStackRequests.clear(); + mConnector = connector; + } + + for (NetworkStackRequest r : requests) { + r.onNetworkStackConnected(connector); + } + } + + /** + * Start the network stack. Should be called only once on device startup. + * + * <p>This method will start the network stack either in the network stack process, or inside + * the system server on devices that do not support the network stack module. The network stack + * connector will then be delivered asynchronously to clients that requested it before it was + * started. + */ + public void start(Context context) { + // Try to bind in-process if the library is available + IBinder connector = null; + try { + final Class service = Class.forName( + "com.android.server.NetworkStackService", + true /* initialize */, + context.getClassLoader()); + connector = (IBinder) service.getMethod("makeConnector").invoke(null); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + Slog.wtf(TAG, "Could not create network stack connector from NetworkStackService"); + // TODO: crash/reboot system here ? + return; + } catch (ClassNotFoundException e) { + // Normal behavior if stack is provided by the app: fall through + } + + // In-process network stack. Add the service to the service manager here. + if (connector != null) { + registerNetworkStackService(connector); + return; + } + // Start the network stack process. The service will be added to the service manager in + // NetworkStackConnection.onServiceConnected(). + final Intent intent = new Intent(INetworkStackConnector.class.getName()); + final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0); + intent.setComponent(comp); + + if (comp == null || !context.bindServiceAsUser(intent, new NetworkStackConnection(), + Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { + Slog.wtf(TAG, + "Could not bind to network stack in-process, or in app with " + intent); + // TODO: crash/reboot system server if no network stack after a timeout ? + } + } + + // TODO: use this method to obtain the connector when implementing network stack operations + private void requestConnector(@NonNull NetworkStackRequest request) { + // TODO: PID check. + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + // Don't even attempt to obtain the connector and give a nice error message + throw new SecurityException( + "Only the system server should try to bind to the network stack."); + } + + final INetworkStackConnector connector; + synchronized (mPendingNetStackRequests) { + connector = mConnector; + if (connector == null) { + mPendingNetStackRequests.add(request); + return; + } + } + + request.onNetworkStackConnected(connector); + } +} diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 3e73d3d2d997..37ab9ffb1f5b 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -17,6 +17,7 @@ package android.net; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -81,7 +82,7 @@ public final class RouteInfo implements Parcelable { // Derived data members. // TODO: remove these. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final boolean mIsHost; private final boolean mHasGateway; @@ -265,7 +266,7 @@ public final class RouteInfo implements Parcelable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean isHost() { return (mDestination.getAddress() instanceof Inet4Address && mDestination.getPrefixLength() == 32) || diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java index 8026d765ee0c..fbc281f26ce8 100644 --- a/core/java/android/net/WebAddress.java +++ b/core/java/android/net/WebAddress.java @@ -20,6 +20,7 @@ import static android.util.Patterns.GOOD_IRI_CHAR; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import java.util.Locale; import java.util.regex.Matcher; @@ -50,7 +51,7 @@ public class WebAddress { private String mScheme; @UnsupportedAppUsage private String mHost; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mPort; @UnsupportedAppUsage private String mPath; diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java index fad6689ed055..b3f2fb79b5c3 100644 --- a/core/java/android/net/http/SslError.java +++ b/core/java/android/net/http/SslError.java @@ -17,6 +17,7 @@ package android.net.http; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import java.security.cert.X509Certificate; /** @@ -68,7 +69,7 @@ public class SslError { * The SSL error set bitfield (each individual error is a bit index; * multiple individual errors can be OR-ed) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mErrors; /** @@ -80,7 +81,7 @@ public class SslError { /** * The URL associated with the error set. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final String mUrl; /** diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index f3810bddf9c7..fdadfbe0ba78 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -58,7 +58,7 @@ public class GraphicsEnvironment { private static final boolean DEBUG = false; private static final String TAG = "GraphicsEnvironment"; private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; - private static final String PROPERTY_GFX_DRIVER_WHITELIST = "ro.gfx.driver.whitelist.0"; + private static final String GUP_WHITELIST_FILENAME = "whitelist.txt"; 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"; @@ -567,22 +567,11 @@ public class GraphicsEnvironment { private static boolean onWhitelist(Context context, String driverPackageName, String applicationPackageName) { - String whitelistName = SystemProperties.get(PROPERTY_GFX_DRIVER_WHITELIST); - - // Empty whitelist implies no updatable graphics driver. Typically, the pre-installed - // updatable graphics driver is supposed to be a place holder and contains no graphics - // driver and whitelist. - if (whitelistName == null || whitelistName.isEmpty()) { - if (DEBUG) { - Log.w(TAG, "No whitelist found."); - } - return false; - } try { Context driverContext = context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED); AssetManager assets = driverContext.getAssets(); - InputStream stream = assets.open(whitelistName); + InputStream stream = assets.open(GUP_WHITELIST_FILENAME); BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); for (String packageName; (packageName = reader.readLine()) != null; ) { if (packageName.equals(applicationPackageName)) { diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 2abcb4cd9379..505aec29d438 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -176,6 +176,12 @@ public class Process { */ public static final int SE_UID = 1068; + /** + * Defines the UID/GID for the NetworkStack app. + * @hide + */ + public static final int NETWORK_STACK_UID = 1073; + /** {@hide} */ public static final int NOBODY_UID = 9999; diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java index 7b6c97132b5c..828f1c304ccb 100644 --- a/core/java/android/os/storage/DiskInfo.java +++ b/core/java/android/os/storage/DiskInfo.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.res.Resources; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -66,7 +67,7 @@ public class DiskInfo implements Parcelable { this.flags = flags; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public DiskInfo(Parcel parcel) { id = parcel.readString(); flags = parcel.readInt(); @@ -196,7 +197,7 @@ public class DiskInfo implements Parcelable { return id.hashCode(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final Creator<DiskInfo> CREATOR = new Creator<DiskInfo>() { @Override public DiskInfo createFromParcel(Parcel in) { diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index f01d5b13b36f..01514646637e 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -123,7 +123,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba mContext = context; mAudioManager = context.getSystemService(AudioManager.class); mNotificationManager = context.getSystemService(NotificationManager.class); - mNotificationPolicy = mNotificationManager.getNotificationPolicy(); + mNotificationPolicy = mNotificationManager.getConsolidatedNotificationPolicy(); mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_ALARMS) != 0; mAllowMedia = (mNotificationPolicy.priorityCategories & NotificationManager.Policy @@ -485,7 +485,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba mZenMode = mNotificationManager.getZenMode(); updateSlider(); } else if (NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED.equals(action)) { - mNotificationPolicy = mNotificationManager.getNotificationPolicy(); + mNotificationPolicy = mNotificationManager.getConsolidatedNotificationPolicy(); mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_ALARMS) != 0; mAllowMedia = (mNotificationPolicy.priorityCategories diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d93985c8ec3d..65514b6f1872 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7957,6 +7957,15 @@ public final class Settings { "night_display_last_activated_time"; /** + * Control whether display white balance is currently enabled. + * @hide + */ + public static final String DISPLAY_WHITE_BALANCE_ENABLED = "display_white_balance_enabled"; + + private static final Validator DISPLAY_WHITE_BALANCE_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** * Names of the service components that the current user has explicitly allowed to * be a VR mode listener, separated by ':'. * @@ -8405,6 +8414,7 @@ public final class Settings { NIGHT_DISPLAY_CUSTOM_END_TIME, NIGHT_DISPLAY_COLOR_TEMPERATURE, NIGHT_DISPLAY_AUTO_MODE, + DISPLAY_WHITE_BALANCE_ENABLED, SYNC_PARENT_SOUNDS, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, SWIPE_UP_TO_SWITCH_APPS_ENABLED, @@ -8552,6 +8562,7 @@ public final class Settings { VALIDATORS.put(NIGHT_DISPLAY_COLOR_TEMPERATURE, NIGHT_DISPLAY_COLOR_TEMPERATURE_VALIDATOR); VALIDATORS.put(NIGHT_DISPLAY_AUTO_MODE, NIGHT_DISPLAY_AUTO_MODE_VALIDATOR); + VALIDATORS.put(DISPLAY_WHITE_BALANCE_ENABLED, DISPLAY_WHITE_BALANCE_ENABLED_VALIDATOR); VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR); VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR); diff --git a/core/java/android/service/autofill/CompositeUserData.java b/core/java/android/service/autofill/CompositeUserData.java new file mode 100644 index 000000000000..2df4ddf7f8ee --- /dev/null +++ b/core/java/android/service/autofill/CompositeUserData.java @@ -0,0 +1,211 @@ +/* + * 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 android.service.autofill; + +import static android.view.autofill.Helper.sDebug; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.TestApi; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +import com.android.internal.util.Preconditions; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * Holds both a generic and package-specific userData used for + * <a href="AutofillService.html#FieldClassification">field classification</a>. + * + * @hide + */ +@TestApi +public final class CompositeUserData implements FieldClassificationUserData, Parcelable { + + private final UserData mGenericUserData; + private final UserData mPackageUserData; + + private final String[] mCategories; + private final String[] mValues; + + public CompositeUserData(@Nullable UserData genericUserData, + @NonNull UserData packageUserData) { + mGenericUserData = genericUserData; + mPackageUserData = packageUserData; + + final String[] packageCategoryIds = mPackageUserData.getCategoryIds(); + final String[] packageValues = mPackageUserData.getValues(); + + final ArrayList<String> categoryIds = new ArrayList<>(packageCategoryIds.length); + final ArrayList<String> values = new ArrayList<>(packageValues.length); + + Collections.addAll(categoryIds, packageCategoryIds); + Collections.addAll(values, packageValues); + + if (mGenericUserData != null) { + final String[] genericCategoryIds = mGenericUserData.getCategoryIds(); + final String[] genericValues = mGenericUserData.getValues(); + final int size = mGenericUserData.getCategoryIds().length; + for (int i = 0; i < size; i++) { + if (!categoryIds.contains(genericCategoryIds[i])) { + categoryIds.add(genericCategoryIds[i]); + values.add(genericValues[i]); + } + } + } + + mCategories = new String[categoryIds.size()]; + categoryIds.toArray(mCategories); + mValues = new String[values.size()]; + values.toArray(mValues); + } + + @Nullable + @Override + public String getFieldClassificationAlgorithm() { + final String packageDefaultAlgo = mPackageUserData.getFieldClassificationAlgorithm(); + if (packageDefaultAlgo != null) { + return packageDefaultAlgo; + } else { + return mGenericUserData == null ? null : + mGenericUserData.getFieldClassificationAlgorithm(); + } + } + + @Override + public Bundle getDefaultFieldClassificationArgs() { + final Bundle packageDefaultArgs = mPackageUserData.getDefaultFieldClassificationArgs(); + if (packageDefaultArgs != null) { + return packageDefaultArgs; + } else { + return mGenericUserData == null ? null : + mGenericUserData.getDefaultFieldClassificationArgs(); + } + } + + @Nullable + @Override + public String getFieldClassificationAlgorithmForCategory(@NonNull String categoryId) { + Preconditions.checkNotNull(categoryId); + final ArrayMap<String, String> categoryAlgorithms = getFieldClassificationAlgorithms(); + if (categoryAlgorithms == null || !categoryAlgorithms.containsKey(categoryId)) { + return null; + } + return categoryAlgorithms.get(categoryId); + } + + @Override + public ArrayMap<String, String> getFieldClassificationAlgorithms() { + final ArrayMap<String, String> packageAlgos = mPackageUserData + .getFieldClassificationAlgorithms(); + final ArrayMap<String, String> genericAlgos = mGenericUserData == null ? null : + mGenericUserData.getFieldClassificationAlgorithms(); + + ArrayMap<String, String> categoryAlgorithms = null; + if (packageAlgos != null || genericAlgos != null) { + categoryAlgorithms = new ArrayMap<>(); + if (genericAlgos != null) { + categoryAlgorithms.putAll(genericAlgos); + } + if (packageAlgos != null) { + categoryAlgorithms.putAll(packageAlgos); + } + } + + return categoryAlgorithms; + } + + @Override + public ArrayMap<String, Bundle> getFieldClassificationArgs() { + final ArrayMap<String, Bundle> packageArgs = mPackageUserData.getFieldClassificationArgs(); + final ArrayMap<String, Bundle> genericArgs = mGenericUserData == null ? null : + mGenericUserData.getFieldClassificationArgs(); + + ArrayMap<String, Bundle> categoryArgs = null; + if (packageArgs != null || genericArgs != null) { + categoryArgs = new ArrayMap<>(); + if (genericArgs != null) { + categoryArgs.putAll(genericArgs); + } + if (packageArgs != null) { + categoryArgs.putAll(packageArgs); + } + } + + return categoryArgs; + } + + @Override + public String[] getCategoryIds() { + return mCategories; + } + + @Override + public String[] getValues() { + return mValues; + } + + ///////////////////////////////////// + // Object "contract" methods. // + ///////////////////////////////////// + @Override + public String toString() { + if (!sDebug) return super.toString(); + + // OK to print UserData because UserData.toString() is PII-aware + final StringBuilder builder = new StringBuilder("genericUserData=") + .append(mGenericUserData) + .append(", packageUserData=").append(mPackageUserData); + return builder.toString(); + } + + ///////////////////////////////////// + // Parcelable "contract" methods. // + ///////////////////////////////////// + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + parcel.writeParcelable(mGenericUserData, 0); + parcel.writeParcelable(mPackageUserData, 0); + } + + public static final Parcelable.Creator<CompositeUserData> CREATOR = + new Parcelable.Creator<CompositeUserData>() { + @Override + public CompositeUserData createFromParcel(Parcel parcel) { + // Always go through the builder to ensure the data ingested by + // the system obeys the contract of the builder to avoid attacks + // using specially crafted parcels. + final UserData genericUserData = parcel.readParcelable(null); + final UserData packageUserData = parcel.readParcelable(null); + return new CompositeUserData(genericUserData, packageUserData); + } + + @Override + public CompositeUserData[] newArray(int size) { + return new CompositeUserData[size]; + } + }; +} diff --git a/core/java/android/service/autofill/FieldClassificationUserData.java b/core/java/android/service/autofill/FieldClassificationUserData.java new file mode 100644 index 000000000000..3d6cac4dca0c --- /dev/null +++ b/core/java/android/service/autofill/FieldClassificationUserData.java @@ -0,0 +1,64 @@ +/* + * 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 android.service.autofill; + +import android.os.Bundle; +import android.util.ArrayMap; + +/** + * Class used to define a generic UserData for field classification + * + * @hide + */ +public interface FieldClassificationUserData { + /** + * Gets the name of the default algorithm that is used to calculate + * {@link FieldClassification.Match#getScore()} match scores}. + */ + String getFieldClassificationAlgorithm(); + + /** + * Gets the default field classification args. + */ + Bundle getDefaultFieldClassificationArgs(); + + /** + * Gets the name of the field classification algorithm for a specific category. + * + * @param categoryId id of the specific category. + */ + String getFieldClassificationAlgorithmForCategory(String categoryId); + + /** + * Gets all field classification algorithms for specific categories. + */ + ArrayMap<String, String> getFieldClassificationAlgorithms(); + + /** + * Gets all field classification args for specific categories. + */ + ArrayMap<String, Bundle> getFieldClassificationArgs(); + + /** + * Gets all category ids + */ + String[] getCategoryIds(); + + /** + * Gets all string values for field classification + */ + String[] getValues(); +} diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java index d408e9a6c3b1..93ee8c33195b 100644 --- a/core/java/android/service/autofill/FillResponse.java +++ b/core/java/android/service/autofill/FillResponse.java @@ -516,6 +516,9 @@ public final class FillResponse implements Parcelable { /** * Sets a specific {@link UserData} for field classification for this request only. * + * <p>Any fields in this UserData will override corresponding fields in the generic + * UserData object + * * @return this builder * @throws IllegalStateException if the FillResponse * {@link #setAuthentication(AutofillId[], IntentSender, RemoteViews) diff --git a/core/java/android/service/autofill/UserData.java b/core/java/android/service/autofill/UserData.java index 37f192366f81..a793e09e79f1 100644 --- a/core/java/android/service/autofill/UserData.java +++ b/core/java/android/service/autofill/UserData.java @@ -48,7 +48,7 @@ import java.util.ArrayList; * Defines the user data used for * <a href="AutofillService.html#FieldClassification">field classification</a>. */ -public final class UserData implements Parcelable { +public final class UserData implements FieldClassificationUserData, Parcelable { private static final String TAG = "UserData"; @@ -86,11 +86,13 @@ public final class UserData implements Parcelable { * {@link Match#getScore()} match scores}. */ @Nullable + @Override public String getFieldClassificationAlgorithm() { return mDefaultAlgorithm; } /** @hide */ + @Override public Bundle getDefaultFieldClassificationArgs() { return mDefaultArgs; } @@ -104,6 +106,7 @@ public final class UserData implements Parcelable { * @return String name of algorithm, null if none found. */ @Nullable + @Override public String getFieldClassificationAlgorithmForCategory(@NonNull String categoryId) { Preconditions.checkNotNull(categoryId); if (mCategoryAlgorithms == null || !mCategoryAlgorithms.containsKey(categoryId)) { @@ -120,22 +123,26 @@ public final class UserData implements Parcelable { } /** @hide */ + @Override public String[] getCategoryIds() { return mCategoryIds; } /** @hide */ + @Override public String[] getValues() { return mValues; } /** @hide */ @TestApi + @Override public ArrayMap<String, String> getFieldClassificationAlgorithms() { return mCategoryAlgorithms; } /** @hide */ + @Override public ArrayMap<String, Bundle> getFieldClassificationArgs() { return mCategoryArgs; } diff --git a/core/java/android/service/autofill/augmented/FillWindow.java b/core/java/android/service/autofill/augmented/FillWindow.java index 27df845ca3e0..bad7ddd3193b 100644 --- a/core/java/android/service/autofill/augmented/FillWindow.java +++ b/core/java/android/service/autofill/augmented/FillWindow.java @@ -163,14 +163,15 @@ public final class FillWindow implements AutoCloseable { final int height = rect.bottom - rect.top; final int width = rect.right - rect.left; final WindowManager.LayoutParams windowParams = window.getAttributes(); - windowParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; - windowParams.y = rect.top - height; + windowParams.gravity = Gravity.TOP | Gravity.LEFT; + windowParams.y = rect.top + height; windowParams.height = height; windowParams.x = rect.left; windowParams.width = width; window.setAttributes(windowParams); window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); + window.setBackgroundDrawableResource(android.R.color.transparent); mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); final ViewGroup.LayoutParams diagParams = new ViewGroup.LayoutParams(width, height); diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java index 64f235546201..c9d46dd701b5 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -31,6 +31,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; +import android.service.autofill.AutofillService; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; @@ -82,6 +83,12 @@ public abstract class ContentCaptureService extends Service { private final IContentCaptureService mServerInterface = new IContentCaptureService.Stub() { @Override + public void onConnectedStateChanged(boolean state) { + mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnConnectedStateChanged, + ContentCaptureService.this, state)); + } + + @Override public void onSessionStarted(ContentCaptureContext context, String sessionId, int uid, IResultReceiver clientReceiver) { mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnCreateSession, @@ -204,6 +211,15 @@ public abstract class ContentCaptureService extends Service { } /** + * Called when the Android system connects to service. + * + * <p>You should generally do initialization here rather than in {@link #onCreate}. + */ + public void onConnected() { + Slog.i(TAG, "bound to " + getClass().getName()); + } + + /** * Creates a new content capture session. * * @param context content capture context @@ -257,6 +273,15 @@ public abstract class ContentCaptureService extends Service { if (VERBOSE) Log.v(TAG, "onDestroyContentCaptureSession(id=" + sessionId + ")"); } + /** + * Called when the Android system disconnects from the service. + * + * <p> At this point this service may no longer be an active {@link AutofillService}. + */ + public void onDisconnected() { + Slog.i(TAG, "unbinding from " + getClass().getName()); + } + @Override @CallSuper protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { @@ -271,6 +296,14 @@ public abstract class ContentCaptureService extends Service { } } + private void handleOnConnectedStateChanged(boolean state) { + if (state) { + onConnected(); + } else { + onDisconnected(); + } + } + //TODO(b/111276913): consider caching the InteractionSessionId for the lifetime of the session, // so we don't need to create a temporary InteractionSessionId for each event. diff --git a/core/java/android/service/contentcapture/IContentCaptureService.aidl b/core/java/android/service/contentcapture/IContentCaptureService.aidl index 20e8e99d4ce1..1b4cccf630a0 100644 --- a/core/java/android/service/contentcapture/IContentCaptureService.aidl +++ b/core/java/android/service/contentcapture/IContentCaptureService.aidl @@ -29,6 +29,7 @@ import java.util.List; * @hide */ oneway interface IContentCaptureService { + void onConnectedStateChanged(boolean state); void onSessionStarted(in ContentCaptureContext context, String sessionId, int uid, in IResultReceiver clientReceiver); void onSessionFinished(String sessionId); diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 6d2f85679cff..0e63cd37f3f2 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -98,7 +98,7 @@ import java.util.List; */ public abstract class NotificationListenerService extends Service { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final String TAG = getClass().getSimpleName(); /** @@ -294,7 +294,7 @@ public abstract class NotificationListenerService extends Service { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) protected INotificationManager mNoMan; /** @@ -516,7 +516,7 @@ public abstract class NotificationListenerService extends Service { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) protected final INotificationManager getNotificationInterface() { if (mNoMan == null) { mNoMan = INotificationManager.Stub.asInterface( diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 84826e0f6824..ad10cc91f34c 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -22,6 +22,7 @@ import android.app.NotificationManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; @@ -35,7 +36,7 @@ public class StatusBarNotification implements Parcelable { private final String pkg; @UnsupportedAppUsage private final int id; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final String tag; private final String key; private String groupKey; @@ -44,13 +45,13 @@ public class StatusBarNotification implements Parcelable { @UnsupportedAppUsage private final int uid; private final String opPkg; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final int initialPid; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Notification notification; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final UserHandle user; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final long postTime; private Context mContext; // used for inflation & icon expansion diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 6792c6935c27..bec654ab65ac 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -16,7 +16,6 @@ package android.service.notification; -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; @@ -126,6 +125,15 @@ public class ZenModeConfig implements Parcelable { private static final String STATE_TAG = "state"; private static final String STATE_ATT_CHANNELS_BYPASSING_DND = "areChannelsBypassingDnd"; + // zen policy visual effects attributes + private static final String SHOW_ATT_FULL_SCREEN_INTENT = "showFullScreenIntent"; + private static final String SHOW_ATT_LIGHTS = "showLights"; + private static final String SHOW_ATT_PEEK = "shoePeek"; + private static final String SHOW_ATT_STATUS_BAR_ICONS = "showStatusBarIcons"; + private static final String SHOW_ATT_BADGES = "showBadges"; + private static final String SHOW_ATT_AMBIENT = "showAmbient"; + private static final String SHOW_ATT_NOTIFICATION_LIST = "showNotificationList"; + private static final String CONDITION_ATT_ID = "id"; private static final String CONDITION_ATT_SUMMARY = "summary"; private static final String CONDITION_ATT_LINE1 = "line1"; @@ -134,6 +142,8 @@ public class ZenModeConfig implements Parcelable { private static final String CONDITION_ATT_STATE = "state"; private static final String CONDITION_ATT_FLAGS = "flags"; + private static final String ZEN_POLICY_TAG = "zen_policy"; + private static final String MANUAL_TAG = "manual"; private static final String AUTOMATIC_TAG = "automatic"; @@ -650,6 +660,7 @@ public class ZenModeConfig implements Parcelable { rt.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; } rt.modified = safeBoolean(parser, RULE_ATT_MODIFIED, false); + rt.zenPolicy = readZenPolicyXml(parser); return rt; } @@ -676,6 +687,9 @@ public class ZenModeConfig implements Parcelable { if (rule.condition != null) { writeConditionXml(rule.condition, out); } + if (rule.zenPolicy != null) { + writeZenPolicyXml(rule.zenPolicy, out); + } out.attribute(null, RULE_ATT_MODIFIED, Boolean.toString(rule.modified)); } @@ -706,6 +720,141 @@ public class ZenModeConfig implements Parcelable { out.attribute(null, CONDITION_ATT_FLAGS, Integer.toString(c.flags)); } + /** + * Read the zen policy from xml + * Returns null if no zen policy exists + */ + public static ZenPolicy readZenPolicyXml(XmlPullParser parser) { + boolean policySet = false; + + ZenPolicy.Builder builder = new ZenPolicy.Builder(); + final int calls = safeInt(parser, ALLOW_ATT_CALLS_FROM, ZenPolicy.PEOPLE_TYPE_UNSET); + final int messages = safeInt(parser, ALLOW_ATT_MESSAGES_FROM, ZenPolicy.PEOPLE_TYPE_UNSET); + final int repeatCallers = safeInt(parser, ALLOW_ATT_REPEAT_CALLERS, ZenPolicy.STATE_UNSET); + final int alarms = safeInt(parser, ALLOW_ATT_ALARMS, ZenPolicy.STATE_UNSET); + final int media = safeInt(parser, ALLOW_ATT_MEDIA, ZenPolicy.STATE_UNSET); + final int system = safeInt(parser, ALLOW_ATT_SYSTEM, ZenPolicy.STATE_UNSET); + final int events = safeInt(parser, ALLOW_ATT_EVENTS, ZenPolicy.STATE_UNSET); + final int reminders = safeInt(parser, ALLOW_ATT_REMINDERS, ZenPolicy.STATE_UNSET); + + if (calls != ZenPolicy.PEOPLE_TYPE_UNSET) { + builder.allowCalls(calls); + policySet = true; + } + if (messages != ZenPolicy.PEOPLE_TYPE_UNSET) { + builder.allowMessages(messages); + policySet = true; + } + if (repeatCallers != ZenPolicy.STATE_UNSET) { + builder.allowRepeatCallers(repeatCallers == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (alarms != ZenPolicy.STATE_UNSET) { + builder.allowAlarms(alarms == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (media != ZenPolicy.STATE_UNSET) { + builder.allowMedia(media == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (system != ZenPolicy.STATE_UNSET) { + builder.allowSystem(system == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (events != ZenPolicy.STATE_UNSET) { + builder.allowEvents(events == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (reminders != ZenPolicy.STATE_UNSET) { + builder.allowReminders(reminders == ZenPolicy.STATE_ALLOW); + policySet = true; + } + + final int fullScreenIntent = safeInt(parser, SHOW_ATT_FULL_SCREEN_INTENT, + ZenPolicy.STATE_UNSET); + final int lights = safeInt(parser, SHOW_ATT_LIGHTS, ZenPolicy.STATE_UNSET); + final int peek = safeInt(parser, SHOW_ATT_PEEK, ZenPolicy.STATE_UNSET); + final int statusBar = safeInt(parser, SHOW_ATT_STATUS_BAR_ICONS, ZenPolicy.STATE_UNSET); + final int badges = safeInt(parser, SHOW_ATT_BADGES, ZenPolicy.STATE_UNSET); + final int ambient = safeInt(parser, SHOW_ATT_AMBIENT, ZenPolicy.STATE_UNSET); + final int notificationList = safeInt(parser, SHOW_ATT_NOTIFICATION_LIST, + ZenPolicy.STATE_UNSET); + + if (fullScreenIntent != ZenPolicy.STATE_UNSET) { + builder.showFullScreenIntent(fullScreenIntent == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (lights != ZenPolicy.STATE_UNSET) { + builder.showLights(lights == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (peek != ZenPolicy.STATE_UNSET) { + builder.showPeeking(peek == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (statusBar != ZenPolicy.STATE_UNSET) { + builder.showStatusBarIcons(statusBar == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (badges != ZenPolicy.STATE_UNSET) { + builder.showBadges(badges == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (ambient != ZenPolicy.STATE_UNSET) { + builder.showInAmbientDisplay(ambient == ZenPolicy.STATE_ALLOW); + policySet = true; + } + if (notificationList != ZenPolicy.STATE_UNSET) { + builder.showInNotificationList(notificationList == ZenPolicy.STATE_ALLOW); + policySet = true; + } + + if (policySet) { + return builder.build(); + } + return null; + } + + /** + * Writes zen policy to xml + */ + public static void writeZenPolicyXml(ZenPolicy policy, XmlSerializer out) + throws IOException { + writeZenPolicyState(ALLOW_ATT_CALLS_FROM, policy.getPriorityCallSenders(), out); + writeZenPolicyState(ALLOW_ATT_MESSAGES_FROM, policy.getPriorityMessageSenders(), out); + writeZenPolicyState(ALLOW_ATT_REPEAT_CALLERS, policy.getPriorityCategoryRepeatCallers(), + out); + writeZenPolicyState(ALLOW_ATT_ALARMS, policy.getPriorityCategoryAlarms(), out); + writeZenPolicyState(ALLOW_ATT_MEDIA, policy.getPriorityCategoryMedia(), out); + writeZenPolicyState(ALLOW_ATT_SYSTEM, policy.getPriorityCategorySystem(), out); + writeZenPolicyState(ALLOW_ATT_REMINDERS, policy.getPriorityCategoryReminders(), out); + writeZenPolicyState(ALLOW_ATT_EVENTS, policy.getPriorityCategoryEvents(), out); + + writeZenPolicyState(SHOW_ATT_FULL_SCREEN_INTENT, policy.getVisualEffectFullScreenIntent(), + out); + writeZenPolicyState(SHOW_ATT_LIGHTS, policy.getVisualEffectLights(), out); + writeZenPolicyState(SHOW_ATT_PEEK, policy.getVisualEffectPeek(), out); + writeZenPolicyState(SHOW_ATT_STATUS_BAR_ICONS, policy.getVisualEffectStatusBar(), out); + writeZenPolicyState(SHOW_ATT_BADGES, policy.getVisualEffectBadge(), out); + writeZenPolicyState(SHOW_ATT_AMBIENT, policy.getVisualEffectAmbient(), out); + writeZenPolicyState(SHOW_ATT_NOTIFICATION_LIST, policy.getVisualEffectNotificationList(), + out); + } + + private static void writeZenPolicyState(String attr, int val, XmlSerializer out) + throws IOException { + if (Objects.equals(attr, ALLOW_ATT_CALLS_FROM) + || Objects.equals(attr, ALLOW_ATT_MESSAGES_FROM)) { + if (val != ZenPolicy.PEOPLE_TYPE_UNSET) { + out.attribute(null, attr, Integer.toString(val)); + } + } else { + if (val != ZenPolicy.STATE_UNSET) { + out.attribute(null, attr, Integer.toString(val)); + } + } + } + public static boolean isValidHour(int val) { return val >= 0 && val < 24; } @@ -798,7 +947,7 @@ public class ZenModeConfig implements Parcelable { if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_REMINDERS, isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_REMINDERS, defaultPolicy))) { - priorityCategories |= PRIORITY_CATEGORY_REMINDERS; + priorityCategories |= Policy.PRIORITY_CATEGORY_REMINDERS; } if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_EVENTS, @@ -839,15 +988,30 @@ public class ZenModeConfig implements Parcelable { priorityCategories |= Policy.PRIORITY_CATEGORY_SYSTEM; } - if (!zenPolicy.isVisualEffectAllowed(ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT, + boolean suppressFullScreenIntent = !zenPolicy.isVisualEffectAllowed( + ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT, isVisualEffectAllowed(Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT, - defaultPolicy))) { + defaultPolicy)); + + boolean suppressLights = !zenPolicy.isVisualEffectAllowed( + ZenPolicy.VISUAL_EFFECT_LIGHTS, + isVisualEffectAllowed(Policy.SUPPRESSED_EFFECT_LIGHTS, + defaultPolicy)); + + boolean suppressAmbient = !zenPolicy.isVisualEffectAllowed( + ZenPolicy.VISUAL_EFFECT_AMBIENT, + isVisualEffectAllowed(Policy.SUPPRESSED_EFFECT_AMBIENT, + defaultPolicy)); + + if (suppressFullScreenIntent && suppressLights && suppressAmbient) { + suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_SCREEN_OFF; + } + + if (suppressFullScreenIntent) { suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT; } - if (!zenPolicy.isVisualEffectAllowed(ZenPolicy.VISUAL_EFFECT_LIGHTS, - isVisualEffectAllowed(Policy.SUPPRESSED_EFFECT_LIGHTS, - defaultPolicy))) { + if (suppressLights) { suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS; } @@ -855,6 +1019,7 @@ public class ZenModeConfig implements Parcelable { isVisualEffectAllowed(Policy.SUPPRESSED_EFFECT_PEEK, defaultPolicy))) { suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_PEEK; + suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_SCREEN_ON; } if (!zenPolicy.isVisualEffectAllowed(ZenPolicy.VISUAL_EFFECT_STATUS_BAR, @@ -869,9 +1034,7 @@ public class ZenModeConfig implements Parcelable { suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_BADGE; } - if (!zenPolicy.isVisualEffectAllowed(ZenPolicy.VISUAL_EFFECT_AMBIENT, - isVisualEffectAllowed(Policy.SUPPRESSED_EFFECT_AMBIENT, - defaultPolicy))) { + if (suppressAmbient) { suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT; } @@ -898,14 +1061,31 @@ public class ZenModeConfig implements Parcelable { case ZenPolicy.PEOPLE_TYPE_ANYONE: return Policy.PRIORITY_SENDERS_ANY; case ZenPolicy.PEOPLE_TYPE_CONTACTS: + return Policy.PRIORITY_SENDERS_CONTACTS; case ZenPolicy.PEOPLE_TYPE_STARRED: default: return Policy.PRIORITY_SENDERS_STARRED; } + } + + /** + * Maps NotificationManager.Policy senders type to ZenPolicy.PeopleType + */ + public static @ZenPolicy.PeopleType int getZenPolicySenders(int senders) { + switch (senders) { + case Policy.PRIORITY_SENDERS_ANY: + return ZenPolicy.PEOPLE_TYPE_ANYONE; + case Policy.PRIORITY_SENDERS_CONTACTS: + return ZenPolicy.PEOPLE_TYPE_CONTACTS; + case Policy.PRIORITY_SENDERS_STARRED: + default: + return ZenPolicy.PEOPLE_TYPE_STARRED; + } } + public Policy toNotificationPolicy() { int priorityCategories = 0; int priorityCallSenders = Policy.PRIORITY_SENDERS_CONTACTS; diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java index 194147c2c154..6392704a680f 100644 --- a/core/java/android/service/notification/ZenPolicy.java +++ b/core/java/android/service/notification/ZenPolicy.java @@ -327,6 +327,32 @@ public final class ZenPolicy implements Parcelable { } /** + * Whether this policy hides all visual effects + * @hide + */ + public boolean shouldHideAllVisualEffects() { + for (int i = 0; i < mVisualEffects.size(); i++) { + if (mVisualEffects.get(i) != STATE_DISALLOW) { + return false; + } + } + return true; + } + + /** + * Whether this policy shows all visual effects + * @hide + */ + public boolean shouldShowAllVisualEffects() { + for (int i = 0; i < mVisualEffects.size(); i++) { + if (mVisualEffects.get(i) != STATE_ALLOW) { + return false; + } + } + return true; + } + + /** * Builder class for {@link ZenPolicy} objects. * Provides a convenient way to set the various fields of a {@link ZenPolicy}. If a field * is not set, it is (@link STATE_UNSET} and will not change the current set policy. @@ -339,6 +365,17 @@ public final class ZenPolicy implements Parcelable { } /** + * @hide + */ + public Builder(ZenPolicy policy) { + if (policy != null) { + mZenPolicy = policy.copy(); + } else { + mZenPolicy = new ZenPolicy(); + } + } + + /** * Builds the current ZenPolicy. */ public ZenPolicy build() { @@ -533,6 +570,34 @@ public final class ZenPolicy implements Parcelable { } /** + * Whether to allow {@link PriorityCategory} sounds to play when DND is active. + * @hide + */ + public Builder allowCategory(@PriorityCategory int category, boolean allow) { + switch (category) { + case PRIORITY_CATEGORY_ALARMS: + allowAlarms(allow); + break; + case PRIORITY_CATEGORY_MEDIA: + allowMedia(allow); + break; + case PRIORITY_CATEGORY_SYSTEM: + allowSystem(allow); + break; + case PRIORITY_CATEGORY_REMINDERS: + allowReminders(allow); + break; + case PRIORITY_CATEGORY_EVENTS: + allowEvents(allow); + break; + case PRIORITY_CATEGORY_REPEAT_CALLERS: + allowRepeatCallers(allow); + break; + } + return this; + } + + /** * Whether {@link Notification#fullScreenIntent full screen intents} that are intercepted * by DND are shown. */ @@ -601,6 +666,38 @@ public final class ZenPolicy implements Parcelable { show ? STATE_ALLOW : STATE_DISALLOW); return this; } + + /** + * Whether notifications intercepted by DND are prevented from appearing for + * {@link VisualEffect} + * @hide + */ + public Builder showVisualEffect(@VisualEffect int effect, boolean show) { + switch (effect) { + case VISUAL_EFFECT_FULL_SCREEN_INTENT: + showFullScreenIntent(show); + break; + case VISUAL_EFFECT_LIGHTS: + showLights(show); + break; + case VISUAL_EFFECT_PEEK: + showPeeking(show); + break; + case VISUAL_EFFECT_STATUS_BAR: + showStatusBarIcons(show); + break; + case VISUAL_EFFECT_BADGE: + showBadges(show); + break; + case VISUAL_EFFECT_AMBIENT: + showInAmbientDisplay(show); + break; + case VISUAL_EFFECT_NOTIFICATION_LIST: + showInNotificationList(show); + break; + } + return this; + } } @Override @@ -640,8 +737,8 @@ public final class ZenPolicy implements Parcelable { .append('{') .append("priorityCategories=[").append(priorityCategoriesToString()) .append("], visualEffects=[").append(visualEffectsToString()) - .append(", priorityCalls=").append(stateToString(mPriorityCalls)) - .append("], priorityMessages=").append(stateToString(mPriorityMessages)) + .append("], priorityCalls=").append(peopleTypeToString(mPriorityCalls)) + .append(", priorityMessages=").append(peopleTypeToString(mPriorityMessages)) .append('}') .toString(); } @@ -726,7 +823,23 @@ public final class ZenPolicy implements Parcelable { case STATE_ALLOW: return "allow"; } - return null; + return "invalidState{" + state + "}"; + } + + private String peopleTypeToString(@PeopleType int peopleType) { + switch (peopleType) { + case PEOPLE_TYPE_ANYONE: + return "anyone"; + case PEOPLE_TYPE_CONTACTS: + return "contacts"; + case PEOPLE_TYPE_NONE: + return "none"; + case PEOPLE_TYPE_STARRED: + return "starred_contacts"; + case STATE_UNSET: + return "unset"; + } + return "invalidPeopleType{" + peopleType + "}"; } @Override @@ -859,27 +972,6 @@ public final class ZenPolicy implements Parcelable { /** * @hide */ - public boolean areValuesSet() { - return getPriorityCategoryReminders() != STATE_UNSET - || getPriorityCategoryEvents() != STATE_UNSET - || getPriorityCategoryMessages() != STATE_UNSET - || getPriorityCategoryCalls() != STATE_UNSET - || getPriorityCategoryRepeatCallers() != STATE_UNSET - || getPriorityCategoryAlarms() != STATE_UNSET - || getPriorityCategoryMedia() != STATE_UNSET - || getPriorityCategorySystem() != STATE_UNSET - || getVisualEffectFullScreenIntent() != STATE_UNSET - || getVisualEffectLights() != STATE_UNSET - || getVisualEffectPeek() != STATE_UNSET - || getVisualEffectStatusBar() != STATE_UNSET - || getVisualEffectBadge() != STATE_UNSET - || getVisualEffectAmbient() != STATE_UNSET - || getVisualEffectNotificationList() != STATE_UNSET; - } - - /** - * @hide - */ public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index f295b705e4e6..a011d677fc6a 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -35,6 +35,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -197,7 +198,7 @@ public abstract class WallpaperService extends Service { final Object mLock = new Object(); boolean mOffsetMessageEnqueued; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) float mPendingXOffset; float mPendingYOffset; float mPendingXOffsetStep; diff --git a/core/java/android/text/method/HideReturnsTransformationMethod.java b/core/java/android/text/method/HideReturnsTransformationMethod.java index e753754a38d4..440a4b187173 100644 --- a/core/java/android/text/method/HideReturnsTransformationMethod.java +++ b/core/java/android/text/method/HideReturnsTransformationMethod.java @@ -17,6 +17,7 @@ package android.text.method; import android.annotation.UnsupportedAppUsage; +import android.os.Build; /** * This transformation method causes any carriage return characters (\r) @@ -50,6 +51,6 @@ extends ReplacementTransformationMethod { return sInstance; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static HideReturnsTransformationMethod sInstance; } diff --git a/core/java/android/text/method/PasswordTransformationMethod.java b/core/java/android/text/method/PasswordTransformationMethod.java index 479fdf4cbb23..c96fc5de0845 100644 --- a/core/java/android/text/method/PasswordTransformationMethod.java +++ b/core/java/android/text/method/PasswordTransformationMethod.java @@ -18,6 +18,7 @@ package android.text.method; import android.annotation.UnsupportedAppUsage; import android.graphics.Rect; +import android.os.Build; import android.os.Handler; import android.os.SystemClock; import android.text.Editable; @@ -264,6 +265,6 @@ implements TransformationMethod, TextWatcher @UnsupportedAppUsage private static PasswordTransformationMethod sInstance; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static char DOT = '\u2022'; } diff --git a/core/java/android/text/style/BulletSpan.java b/core/java/android/text/style/BulletSpan.java index 679698bbfb55..9b1dfbfc95e6 100644 --- a/core/java/android/text/style/BulletSpan.java +++ b/core/java/android/text/style/BulletSpan.java @@ -24,6 +24,7 @@ import android.annotation.Px; import android.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Paint; +import android.os.Build; import android.os.Parcel; import android.text.Layout; import android.text.ParcelableSpan; @@ -69,14 +70,14 @@ public class BulletSpan implements LeadingMarginSpan, ParcelableSpan { private static final int STANDARD_COLOR = 0; @Px - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final int mGapWidth; @Px private final int mBulletRadius; @ColorInt - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final int mColor; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final boolean mWantColor; /** diff --git a/core/java/android/util/DebugUtils.java b/core/java/android/util/DebugUtils.java index e87fcff3ee4b..af73a16e012a 100644 --- a/core/java/android/util/DebugUtils.java +++ b/core/java/android/util/DebugUtils.java @@ -17,6 +17,7 @@ package android.util; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -109,7 +110,7 @@ public class DebugUtils { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static void buildShortClassTag(Object cls, StringBuilder out) { if (cls == null) { out.append("null"); diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java index 55245065c082..f31ddd9b0307 100644 --- a/core/java/android/util/Range.java +++ b/core/java/android/util/Range.java @@ -28,7 +28,7 @@ import android.hardware.camera2.utils.HashCodeHelpers; * "integers from 1 to 100 inclusive." * </p> * <p> - * All ranges are bounded, and the left side of the range is always {@code >=} + * All ranges are bounded, and the left side of the range is always {@code <=} * the right side of the range. * </p> * diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java index c9fc3f2d1bcc..a85120f67f8d 100644 --- a/core/java/android/util/Slog.java +++ b/core/java/android/util/Slog.java @@ -17,6 +17,7 @@ package android.util; import android.annotation.UnsupportedAppUsage; +import android.os.Build; /** * @hide @@ -105,7 +106,7 @@ public final class Slog { * will always be handled asynchronously. Primarily for use by coding running within * the system process. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static int wtfStack(String tag, String msg) { return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, null, true, true); } diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java index 57d55bf31375..91bc3eb5f83a 100644 --- a/core/java/android/util/TimeUtils.java +++ b/core/java/android/util/TimeUtils.java @@ -19,6 +19,7 @@ package android.util; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.SystemClock; import libcore.timezone.CountryTimeZones; @@ -289,7 +290,7 @@ public class TimeUtils { } /** @hide Just for debugging; not internationalized. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static void formatDuration(long duration, PrintWriter pw, int fieldLen) { synchronized (sFormatSync) { int len = formatDurationLocked(duration, fieldLen); @@ -306,7 +307,7 @@ public class TimeUtils { } /** @hide Just for debugging; not internationalized. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static void formatDuration(long duration, PrintWriter pw) { formatDuration(duration, pw, 0); } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 9dfd43cde628..330d72f139db 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -107,12 +107,6 @@ interface IWindowManager */ void endProlongedAnimations(); - // Re-evaluate the current orientation from the caller's state. - // If there is a change, the new Configuration is returned and the - // caller must call setNewConfiguration() sometime later. - Configuration updateOrientationFromAppTokens(in Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId); - void startFreezingScreen(int exitAnim, int enterAnim); void stopFreezingScreen(); diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 97625869209d..d1115c7b4d1d 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -250,4 +250,10 @@ interface IWindowSession { */ void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width, int height); + + /** + * Called when the client has changed the local insets state, and now the server should reflect + * that new state. + */ + void insetsModified(IWindow window, in InsetsState state); } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 4ab1f266cc70..01af37e75cb9 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -19,7 +19,9 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; +import android.os.RemoteException; import android.util.ArraySet; +import android.util.Log; import android.util.SparseArray; import android.view.SurfaceControl.Transaction; import android.view.WindowInsets.Type.InsetType; @@ -36,7 +38,11 @@ import java.util.ArrayList; */ public class InsetsController implements WindowInsetsController { + private final String TAG = "InsetsControllerImpl"; + private final InsetsState mState = new InsetsState(); + private final InsetsState mTmpState = new InsetsState(); + private final Rect mFrame = new Rect(); private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>(); private final ViewRootImpl mViewRoot; @@ -61,8 +67,12 @@ public class InsetsController implements WindowInsetsController { return false; } mState.set(state); + mTmpState.set(state, true /* copySources */); applyLocalVisibilityOverride(); mViewRoot.notifyInsetsChanged(); + if (!mState.equals(mTmpState)) { + sendStateToWindowManager(); + } return true; } @@ -163,6 +173,27 @@ public class InsetsController implements WindowInsetsController { @VisibleForTesting public void notifyVisibilityChanged() { mViewRoot.notifyInsetsChanged(); + sendStateToWindowManager(); + } + + /** + * Sends the local visibility state back to window manager. + */ + private void sendStateToWindowManager() { + InsetsState tmpState = new InsetsState(); + for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { + final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); + if (consumer.getControl() != null) { + tmpState.addSource(mState.getSource(consumer.getType())); + } + } + + // TODO: Put this on a dispatcher thread. + try { + mViewRoot.mWindowSession.insetsModified(mViewRoot.mWindow, tmpState); + } catch (RemoteException e) { + Log.e(TAG, "Failed to call insetsModified", e); + } } void dump(String prefix, PrintWriter pw) { diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java index f8148a906bb3..fbc72a0f978e 100644 --- a/core/java/android/view/InsetsSource.java +++ b/core/java/android/view/InsetsSource.java @@ -65,6 +65,10 @@ public class InsetsSource implements Parcelable { return mFrame; } + public boolean isVisible() { + return mVisible; + } + /** * Calculates the insets this source will cause to a client window. * diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java index ec85c4c56cfc..145b09763676 100644 --- a/core/java/android/view/InsetsSourceConsumer.java +++ b/core/java/android/view/InsetsSourceConsumer.java @@ -35,7 +35,7 @@ public class InsetsSourceConsumer { private final InsetsState mState; private final InsetsController mController; private @Nullable InsetsSourceControl mSourceControl; - private boolean mHidden; + private boolean mVisible; public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state, Supplier<Transaction> transactionSupplier, InsetsController controller) { @@ -43,6 +43,7 @@ public class InsetsSourceConsumer { mState = state; mTransactionSupplier = transactionSupplier; mController = controller; + mVisible = InsetsState.getDefaultVisibly(type); } public void setControl(@Nullable InsetsSourceControl control) { @@ -51,8 +52,9 @@ public class InsetsSourceConsumer { } mSourceControl = control; applyHiddenToControl(); - applyLocalVisibilityOverride(); - mController.notifyVisibilityChanged(); + if (applyLocalVisibilityOverride()) { + mController.notifyVisibilityChanged(); + } } @VisibleForTesting @@ -66,28 +68,32 @@ public class InsetsSourceConsumer { @VisibleForTesting public void show() { - setHidden(false); + setVisible(true); } @VisibleForTesting public void hide() { - setHidden(true); + setVisible(false); } - void applyLocalVisibilityOverride() { + boolean applyLocalVisibilityOverride() { // If we don't have control, we are not able to change the visibility. if (mSourceControl == null) { - return; + return false; + } + if (mState.getSource(mType).isVisible() == mVisible) { + return false; } - mState.getSource(mType).setVisible(!mHidden); + mState.getSource(mType).setVisible(mVisible); + return true; } - private void setHidden(boolean hidden) { - if (mHidden == hidden) { + private void setVisible(boolean visible) { + if (mVisible == visible) { return; } - mHidden = hidden; + mVisible = visible; applyHiddenToControl(); applyLocalVisibilityOverride(); mController.notifyVisibilityChanged(); @@ -100,10 +106,10 @@ public class InsetsSourceConsumer { // TODO: Animation final Transaction t = mTransactionSupplier.get(); - if (mHidden) { - t.hide(mSourceControl.getLeash()); - } else { + if (mVisible) { t.show(mSourceControl.getLeash()); + } else { + t.hide(mSourceControl.getLeash()); } t.apply(); } diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 63025dc16f17..3f8f882a869f 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -32,6 +32,7 @@ import android.view.WindowInsets.Type.InsetType; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; /** * Holder for state of system windows that cause window insets for all other windows in the system. @@ -200,6 +201,18 @@ public class InsetsState implements Parcelable { } } + public void addSource(InsetsSource source) { + mSources.put(source.getType(), source); + } + + public int getSourcesCount() { + return mSources.size(); + } + + public InsetsSource sourceAt(int index) { + return mSources.valueAt(index); + } + public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) { final ArraySet<Integer> result = new ArraySet<>(); if ((insetTypes & Type.TOP_BAR) != 0) { @@ -216,6 +229,20 @@ public class InsetsState implements Parcelable { return result; } + public static boolean getDefaultVisibly(@InsetType int type) { + switch (type) { + case TYPE_TOP_BAR: + case TYPE_SIDE_BAR_1: + case TYPE_SIDE_BAR_2: + case TYPE_SIDE_BAR_3: + return true; + case TYPE_IME: + return false; + default: + return true; + } + } + public void dump(String prefix, PrintWriter pw) { pw.println(prefix + "InsetsState"); for (int i = mSources.size() - 1; i >= 0; i--) { diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index a4d3ce7e20bd..be81c06de1af 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -921,127 +921,127 @@ public abstract class LayoutInflater { AttributeSet attrs) throws XmlPullParserException, IOException { int type; - if (parent instanceof ViewGroup) { - // Apply a theme wrapper, if requested. This is sort of a weird - // edge case, since developers think the <include> overwrites - // values in the AttributeSet of the included View. So, if the - // included View has a theme attribute, we'll need to ignore it. - final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); - final int themeResId = ta.getResourceId(0, 0); - final boolean hasThemeOverride = themeResId != 0; - if (hasThemeOverride) { - context = new ContextThemeWrapper(context, themeResId); - } - ta.recycle(); - - // If the layout is pointing to a theme attribute, we have to - // massage the value to get a resource identifier out of it. - int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0); - if (layout == 0) { - final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); - if (value == null || value.length() <= 0) { - throw new InflateException("You must specify a layout in the" - + " include tag: <include layout=\"@layout/layoutID\" />"); - } + if (!(parent instanceof ViewGroup)) { + throw new InflateException("<include /> can only be used inside of a ViewGroup"); + } - // Attempt to resolve the "?attr/name" string to an attribute - // within the default (e.g. application) package. - layout = context.getResources().getIdentifier( - value.substring(1), "attr", context.getPackageName()); + // Apply a theme wrapper, if requested. This is sort of a weird + // edge case, since developers think the <include> overwrites + // values in the AttributeSet of the included View. So, if the + // included View has a theme attribute, we'll need to ignore it. + final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); + final int themeResId = ta.getResourceId(0, 0); + final boolean hasThemeOverride = themeResId != 0; + if (hasThemeOverride) { + context = new ContextThemeWrapper(context, themeResId); + } + ta.recycle(); + // If the layout is pointing to a theme attribute, we have to + // massage the value to get a resource identifier out of it. + int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0); + if (layout == 0) { + final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); + if (value == null || value.length() <= 0) { + throw new InflateException("You must specify a layout in the" + + " include tag: <include layout=\"@layout/layoutID\" />"); } - // The layout might be referencing a theme attribute. - if (mTempValue == null) { - mTempValue = new TypedValue(); - } - if (layout != 0 && context.getTheme().resolveAttribute(layout, mTempValue, true)) { - layout = mTempValue.resourceId; - } + // Attempt to resolve the "?attr/name" string to an attribute + // within the default (e.g. application) package. + layout = context.getResources().getIdentifier( + value.substring(1), "attr", context.getPackageName()); - if (layout == 0) { - final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); - throw new InflateException("You must specify a valid layout " - + "reference. The layout ID " + value + " is not valid."); - } else { - final XmlResourceParser childParser = context.getResources().getLayout(layout); + } - try { - final AttributeSet childAttrs = Xml.asAttributeSet(childParser); + // The layout might be referencing a theme attribute. + if (mTempValue == null) { + mTempValue = new TypedValue(); + } + if (layout != 0 && context.getTheme().resolveAttribute(layout, mTempValue, true)) { + layout = mTempValue.resourceId; + } - while ((type = childParser.next()) != XmlPullParser.START_TAG && - type != XmlPullParser.END_DOCUMENT) { - // Empty. - } + if (layout == 0) { + final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); + throw new InflateException("You must specify a valid layout " + + "reference. The layout ID " + value + " is not valid."); + } - if (type != XmlPullParser.START_TAG) { - throw new InflateException(childParser.getPositionDescription() + - ": No start tag found!"); - } + final XmlResourceParser childParser = context.getResources().getLayout(layout); - final String childName = childParser.getName(); + try { + final AttributeSet childAttrs = Xml.asAttributeSet(childParser); - if (TAG_MERGE.equals(childName)) { - // The <merge> tag doesn't support android:theme, so - // nothing special to do here. - rInflate(childParser, parent, context, childAttrs, false); - } else { - final View view = createViewFromTag(parent, childName, - context, childAttrs, hasThemeOverride); - final ViewGroup group = (ViewGroup) parent; - - final TypedArray a = context.obtainStyledAttributes( - attrs, R.styleable.Include); - final int id = a.getResourceId(R.styleable.Include_id, View.NO_ID); - final int visibility = a.getInt(R.styleable.Include_visibility, -1); - a.recycle(); - - // We try to load the layout params set in the <include /> tag. - // If the parent can't generate layout params (ex. missing width - // or height for the framework ViewGroups, though this is not - // necessarily true of all ViewGroups) then we expect it to throw - // a runtime exception. - // We catch this exception and set localParams accordingly: true - // means we successfully loaded layout params from the <include> - // tag, false means we need to rely on the included layout params. - ViewGroup.LayoutParams params = null; - try { - params = group.generateLayoutParams(attrs); - } catch (RuntimeException e) { - // Ignore, just fail over to child attrs. - } - if (params == null) { - params = group.generateLayoutParams(childAttrs); - } - view.setLayoutParams(params); + while ((type = childParser.next()) != XmlPullParser.START_TAG && + type != XmlPullParser.END_DOCUMENT) { + // Empty. + } - // Inflate all children. - rInflateChildren(childParser, view, childAttrs, true); + if (type != XmlPullParser.START_TAG) { + throw new InflateException(childParser.getPositionDescription() + + ": No start tag found!"); + } - if (id != View.NO_ID) { - view.setId(id); - } + final String childName = childParser.getName(); - switch (visibility) { - case 0: - view.setVisibility(View.VISIBLE); - break; - case 1: - view.setVisibility(View.INVISIBLE); - break; - case 2: - view.setVisibility(View.GONE); - break; - } + if (TAG_MERGE.equals(childName)) { + // The <merge> tag doesn't support android:theme, so + // nothing special to do here. + rInflate(childParser, parent, context, childAttrs, false); + } else { + final View view = createViewFromTag(parent, childName, + context, childAttrs, hasThemeOverride); + final ViewGroup group = (ViewGroup) parent; + + final TypedArray a = context.obtainStyledAttributes( + attrs, R.styleable.Include); + final int id = a.getResourceId(R.styleable.Include_id, View.NO_ID); + final int visibility = a.getInt(R.styleable.Include_visibility, -1); + a.recycle(); + + // We try to load the layout params set in the <include /> tag. + // If the parent can't generate layout params (ex. missing width + // or height for the framework ViewGroups, though this is not + // necessarily true of all ViewGroups) then we expect it to throw + // a runtime exception. + // We catch this exception and set localParams accordingly: true + // means we successfully loaded layout params from the <include> + // tag, false means we need to rely on the included layout params. + ViewGroup.LayoutParams params = null; + try { + params = group.generateLayoutParams(attrs); + } catch (RuntimeException e) { + // Ignore, just fail over to child attrs. + } + if (params == null) { + params = group.generateLayoutParams(childAttrs); + } + view.setLayoutParams(params); - group.addView(view); - } - } finally { - childParser.close(); + // Inflate all children. + rInflateChildren(childParser, view, childAttrs, true); + + if (id != View.NO_ID) { + view.setId(id); + } + + switch (visibility) { + case 0: + view.setVisibility(View.VISIBLE); + break; + case 1: + view.setVisibility(View.INVISIBLE); + break; + case 2: + view.setVisibility(View.GONE); + break; } + + group.addView(view); } - } else { - throw new InflateException("<include /> can only be used inside of a ViewGroup"); + } finally { + childParser.close(); } LayoutInflater.consumeChildElements(parser); diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java index 60eeeeaa77ff..f8d5014a29c9 100644 --- a/core/java/android/view/NotificationHeaderView.java +++ b/core/java/android/view/NotificationHeaderView.java @@ -195,12 +195,10 @@ public class NotificationHeaderView extends ViewGroup { } int childHeight = child.getMeasuredHeight(); MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams(); - left += params.getMarginStart(); - int right = left + child.getMeasuredWidth(); + int layoutLeft; + int layoutRight; int top = (int) (getPaddingTop() + (ownHeight - childHeight) / 2.0f); int bottom = top + childHeight; - int layoutLeft = left; - int layoutRight = right; if ((child == mExpandButton && mShowExpandButtonAtEnd) || child == mProfileBadge || child == mAppOps) { @@ -211,6 +209,12 @@ public class NotificationHeaderView extends ViewGroup { } layoutLeft = layoutRight - child.getMeasuredWidth(); end = layoutLeft - params.getMarginStart(); + } else { + left += params.getMarginStart(); + int right = left + child.getMeasuredWidth(); + layoutLeft = left; + layoutRight = right; + left = right + params.getMarginEnd(); } if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) { int ltrLeft = layoutLeft; @@ -218,7 +222,6 @@ public class NotificationHeaderView extends ViewGroup { layoutRight = getWidth() - ltrLeft; } child.layout(layoutLeft, top, layoutRight, bottom); - left = right + params.getMarginEnd(); } updateTouchListener(); } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 797d1c5f47aa..a0af83d17abd 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -110,7 +110,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb final ReentrantLock mSurfaceLock = new ReentrantLock(); @UnsupportedAppUsage final Surface mSurface = new Surface(); // Current surface in use - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) boolean mDrawingStopped = true; // We use this to track if the application has produced a frame // in to the Surface. Up until that point, we should be careful not to punch @@ -129,7 +129,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb int mSubLayer = APPLICATION_MEDIA_SUBLAYER; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) boolean mIsCreating = false; private volatile boolean mRtHandlingPositionUpdates = false; @@ -159,9 +159,9 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb boolean mViewVisibility = false; boolean mWindowStopped = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mRequestedWidth = -1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mRequestedHeight = -1; /* Set SurfaceView's format to 565 by default to maintain backward * compatibility with applications assuming this format. @@ -172,7 +172,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb @UnsupportedAppUsage boolean mHaveFrame = false; boolean mSurfaceCreated = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) long mLastLockTime = 0; boolean mVisible = false; @@ -182,7 +182,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb int mSurfaceHeight = -1; @UnsupportedAppUsage int mFormat = -1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final Rect mSurfaceFrame = new Rect(); int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; private Translator mTranslator; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 57635efff72e..6b07efc0b448 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4683,7 +4683,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * a long press could be performed before the tap is checked, in which case the tap's action * should not be invoked. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mHasPerformedLongPress; /** @@ -14840,7 +14840,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param flags Constant indicating the value which should be set * @param mask Constant indicating the bit range that should be changed */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) void setFlags(int flags, int mask) { final boolean accessibilityEnabled = AccessibilityManager.getInstance(mContext).isEnabled(); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 741510e67130..8372032593b0 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -143,7 +143,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager protected OnHierarchyChangeListener mOnHierarchyChangeListener; // The view contained within this ViewGroup that has or contains focus. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private View mFocused; // The view contained within this ViewGroup (excluding nested keyboard navigation clusters) // that is or contains a default-focus view. diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 58ab817c6faf..097f368ac2a8 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -38,6 +38,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.media.session.MediaController; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -282,7 +283,7 @@ public abstract class Window { private WindowControllerCallback mWindowControllerCallback; private OnRestrictedCaptionAreaChangedListener mOnRestrictedCaptionAreaChangedListener; private Rect mRestrictedCaptionAreaRect; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private WindowManager mWindowManager; @UnsupportedAppUsage private IBinder mAppToken; @@ -1296,7 +1297,7 @@ public abstract class Window { public abstract void alwaysReadCloseOnTouchAttr(); /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean shouldCloseOnTouch(Context context, MotionEvent event) { final boolean isOutside = event.getAction() == MotionEvent.ACTION_DOWN && isOutOfBounds(context, event) diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index 0e1f7675c8c3..95a346f34d24 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -30,6 +30,9 @@ import android.util.TypedValue; import dalvik.system.CloseGuard; +import java.util.ArrayList; +import java.util.List; + /** * Abstraction for an Animation that can be applied to Views, Surfaces, or * other objects. See the {@link android.view.animation animation package @@ -182,10 +185,14 @@ public abstract class Animation implements Cloneable { Interpolator mInterpolator; /** - * The animation listener to be notified when the animation starts, ends or repeats. + * An animation listener to be notified when the animation starts, ends or repeats. */ - @UnsupportedAppUsage - AnimationListener mListener; + private AnimationListener mListener; + + /** + * A list of animation listeners to be notified when the animation starts, ends or repeats. + */ + private List<AnimationListener> mListeners; /** * Desired Z order mode during animation. @@ -371,23 +378,17 @@ public abstract class Animation implements Cloneable { if (mListenerHandler == null) { mOnStart = new Runnable() { public void run() { - if (mListener != null) { - mListener.onAnimationStart(Animation.this); - } + dispatchAnimationStart(); } }; mOnRepeat = new Runnable() { public void run() { - if (mListener != null) { - mListener.onAnimationRepeat(Animation.this); - } + dispatchAnimationRepeat(); } }; mOnEnd = new Runnable() { public void run() { - if (mListener != null) { - mListener.onAnimationEnd(Animation.this); - } + dispatchAnimationEnd(); } }; } @@ -830,6 +831,10 @@ public abstract class Animation implements Cloneable { return true; } + private boolean hasAnimationListener() { + return mListener != null || (mListeners != null && !mListeners.isEmpty()); + } + /** * <p>Binds an animation listener to this animation. The animation listener * is notified of animation events such as the end of the animation or the @@ -842,6 +847,32 @@ public abstract class Animation implements Cloneable { } /** + * <p>Adds an animation listener to this animation. The animation listener + * is notified of animation events such as the end of the animation or the + * repetition of the animation.</p> + * + * @param listener the animation listener to be notified + */ + public void addAnimationListener(AnimationListener listener) { + if (mListeners == null) { + mListeners = new ArrayList<>(1); + } + mListeners.add(listener); + } + + /** + * <p>Removes an animation listener that has been added with + * {@link #addAnimationListener(AnimationListener)}.</p> + * + * @param listener the animation listener to be removed + */ + public void removeAnimationListener(AnimationListener listener) { + if (mListeners != null) { + mListeners.remove(listener); + } + } + + /** * Gurantees that this animation has an interpolator. Will use * a AccelerateDecelerateInterpolator is nothing else was specified. */ @@ -947,26 +978,59 @@ public abstract class Animation implements Cloneable { } private void fireAnimationStart() { - if (mListener != null) { - if (mListenerHandler == null) mListener.onAnimationStart(this); + if (hasAnimationListener()) { + if (mListenerHandler == null) dispatchAnimationStart(); else mListenerHandler.postAtFrontOfQueue(mOnStart); } } private void fireAnimationRepeat() { - if (mListener != null) { - if (mListenerHandler == null) mListener.onAnimationRepeat(this); + if (hasAnimationListener()) { + if (mListenerHandler == null) dispatchAnimationRepeat(); else mListenerHandler.postAtFrontOfQueue(mOnRepeat); } } private void fireAnimationEnd() { - if (mListener != null) { - if (mListenerHandler == null) mListener.onAnimationEnd(this); + if (hasAnimationListener()) { + if (mListenerHandler == null) dispatchAnimationEnd(); else mListenerHandler.postAtFrontOfQueue(mOnEnd); } } + void dispatchAnimationStart() { + if (mListener != null) { + mListener.onAnimationStart(this); + } + if (mListeners != null && !mListeners.isEmpty()) { + for (AnimationListener listener : mListeners) { + listener.onAnimationStart(this); + } + } + } + + void dispatchAnimationRepeat() { + if (mListener != null) { + mListener.onAnimationRepeat(this); + } + if (mListeners != null && !mListeners.isEmpty()) { + for (AnimationListener listener : mListeners) { + listener.onAnimationRepeat(this); + } + } + } + + void dispatchAnimationEnd() { + if (mListener != null) { + mListener.onAnimationEnd(this); + } + if (mListeners != null && !mListeners.isEmpty()) { + for (AnimationListener listener : mListeners) { + listener.onAnimationEnd(this); + } + } + } + /** * Gets the transformation to apply at a specified point in time. Implementations of this * method should always replace the specified Transformation or document they are doing diff --git a/core/java/android/view/animation/AnimationSet.java b/core/java/android/view/animation/AnimationSet.java index 767024ecfecf..03c6ca69a592 100644 --- a/core/java/android/view/animation/AnimationSet.java +++ b/core/java/android/view/animation/AnimationSet.java @@ -389,16 +389,12 @@ public class AnimationSet extends Animation { } if (started && !mStarted) { - if (mListener != null) { - mListener.onAnimationStart(this); - } + dispatchAnimationStart(); mStarted = true; } if (ended != mEnded) { - if (mListener != null) { - mListener.onAnimationEnd(this); - } + dispatchAnimationEnd(); mEnded = ended; } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 699b34abd45d..56f973eb9e46 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -77,7 +77,6 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; - //TODO: use java.lang.ref.Cleaner once Android supports Java 9 import sun.misc.Cleaner; @@ -2966,12 +2965,13 @@ public final class AutofillManager { if (afm == null) return null; final View view = afm.getClient().autofillClientFindViewByAutofillIdTraversal(id); - // TODO(b/111330312): optimize (for example, use temp rect from attach info) and - // fix (for example, take system status bar height into account) logic below + final Rect windowVisibleDisplayFrame = new Rect(); + view.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame); final int[] location = new int[2]; view.getLocationOnScreen(location); - final Rect rect = new Rect(location[0], location[1], location[0] + view.getWidth(), - location[1] + view.getHeight()); + final Rect rect = new Rect(location[0], location[1] - windowVisibleDisplayFrame.top, + location[0] + view.getWidth(), + location[1] - windowVisibleDisplayFrame.top + view.getHeight()); if (sVerbose) { Log.v(TAG, "Coordinates for " + id + ": " + rect); } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index ea6f2fe16ef6..92e0187f5b0f 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -258,14 +258,27 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } mEvents = new ArrayList<>(MAX_BUFFER_SIZE); } - mEvents.add(event); + + if (!mEvents.isEmpty() && event.getType() == TYPE_VIEW_TEXT_CHANGED) { + final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1); + + // TODO(b/121045053): check if flags match + if (lastEvent.getType() == TYPE_VIEW_TEXT_CHANGED + && lastEvent.getId().equals(event.getId())) { + if (VERBOSE) { + Log.v(mTag, "Buffering VIEW_TEXT_CHANGED event, updated text = " + + event.getText()); + } + lastEvent.setText(event.getText()); + } else { + mEvents.add(event); + } + } else { + mEvents.add(event); + } final int numberEvents = mEvents.size(); - // TODO(b/120784831): need to optimize it so we buffer changes until a number of X are - // buffered (either total or per autofillid). For - // example, if the user typed "a", "b", "c" and the threshold is 3, we should buffer - // "a" and "b" then send "abc". final boolean bufferEvent = numberEvents < MAX_BUFFER_SIZE; if (bufferEvent && !forceFlush) { diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index e57fdffdfd1a..1ba7d8ed5db2 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -26,6 +26,8 @@ import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; +import android.app.ActivityThread; +import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Rect; @@ -37,11 +39,13 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.Trace; +import android.provider.Settings; import android.text.style.SuggestionSpan; import android.util.Log; import android.util.Pools.Pool; @@ -76,9 +80,9 @@ import com.android.internal.view.InputBindResult; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.reflect.Proxy; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -232,6 +236,15 @@ public final class InputMethodManager { static final String PENDING_EVENT_COUNTER = "aq:imm"; + private static final int NOT_A_SUBTYPE_ID = -1; + + /** + * A constant that represents Voice IME. + * + * @see InputMethodSubtype#getMode() + */ + private static final String SUBTYPE_MODE_VOICE = "voice"; + /** * Ensures that {@link #sInstance} becomes non-{@code null} for application that have directly * or indirectly relied on {@link #sInstance} via reflection or something like that. @@ -2064,6 +2077,13 @@ public final class InputMethodManager { /** * Force switch to a new input method component. This can only be called * from an application or a service which has a token of the currently active input method. + * + * <p>On Android {@link Build.VERSION_CODES#Q} and later devices, the undocumented behavior that + * token can be {@code null} when the caller has + * {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} is deprecated. Instead, update + * {@link android.provider.Settings.Secure#DEFAULT_INPUT_METHOD} and + * {@link android.provider.Settings.Secure#SELECTED_INPUT_METHOD_SUBTYPE} directly.</p> + * * @param token Supplies the identifying token given to an input method * when it was started, which allows it to perform this operation on * itself. @@ -2075,14 +2095,50 @@ public final class InputMethodManager { @Deprecated public void setInputMethod(IBinder token, String id) { if (token == null) { - // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission. - // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately. - // TODO(Bug 114488811): Consider deprecating null token rule. - try { - mService.setInputMethod(token, id); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + // There are still some system components that rely on this undocumented behavior + // regarding null IME token with WRITE_SECURE_SETTINGS. Provide a fallback logic as a + // temporary remedy. + if (id == null) { + return; + } + if (Process.myUid() == Process.SYSTEM_UID) { + Log.w(TAG, "System process should not be calling setInputMethod() because almost " + + "always it is a bug under multi-user / multi-profile environment. " + + "Consider interacting with InputMethodManagerService directly via " + + "LocalServices."); + return; + } + final Context fallbackContext = ActivityThread.currentApplication(); + if (fallbackContext == null) { + return; + } + if (fallbackContext.checkSelfPermission(WRITE_SECURE_SETTINGS) + != PackageManager.PERMISSION_GRANTED) { + return; } + final List<InputMethodInfo> imis = getEnabledInputMethodList(); + final int numImis = imis.size(); + boolean found = false; + for (int i = 0; i < numImis; ++i) { + final InputMethodInfo imi = imis.get(i); + if (id.equals(imi.getId())) { + found = true; + break; + } + } + if (!found) { + Log.e(TAG, "Ignoring setInputMethod(null, " + id + ") because the specified " + + "id not found in enabled IMEs."); + return; + } + Log.w(TAG, "The undocumented behavior that setInputMethod() accepts null token " + + "when the caller has WRITE_SECURE_SETTINGS is deprecated. This behavior may " + + "be completely removed in a future version. Update secure settings directly " + + "instead."); + final ContentResolver resolver = fallbackContext.getContentResolver(); + Settings.Secure.putInt(resolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, + NOT_A_SUBTYPE_ID); + Settings.Secure.putString(resolver, Settings.Secure.DEFAULT_INPUT_METHOD, id); return; } InputMethodPrivilegedOperationsRegistry.get(token).setInputMethod(id); @@ -2091,6 +2147,12 @@ public final class InputMethodManager { /** * Force switch to a new input method and subtype. This can only be called * from an application or a service which has a token of the currently active input method. + * + * <p>On Android {@link Build.VERSION_CODES#Q} and later devices, {@code token} cannot be + * {@code null} even with {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}. Instead, + * update {@link android.provider.Settings.Secure#DEFAULT_INPUT_METHOD} and + * {@link android.provider.Settings.Secure#SELECTED_INPUT_METHOD_SUBTYPE} directly.</p> + * * @param token Supplies the identifying token given to an input method * when it was started, which allows it to perform this operation on * itself. @@ -2102,16 +2164,11 @@ public final class InputMethodManager { * the service. APIs in this class are intended for app developers interacting with the IME. */ @Deprecated - public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) { + public void setInputMethodAndSubtype(@NonNull IBinder token, String id, + InputMethodSubtype subtype) { if (token == null) { - // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission. - // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately. - // TODO(Bug 114488811): Consider deprecating null token rule. - try { - mService.setInputMethodAndSubtype(token, id, subtype); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + Log.e(TAG, "setInputMethodAndSubtype() does not accept null token on Android Q " + + "and later."); return; } InputMethodPrivilegedOperationsRegistry.get(token).setInputMethodAndSubtype(id, subtype); @@ -2459,34 +2516,25 @@ public final class InputMethodManager { * Returns a map of all shortcut input method info and their subtypes. */ public Map<InputMethodInfo, List<InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() { - synchronized (mH) { - HashMap<InputMethodInfo, List<InputMethodSubtype>> ret = new HashMap<>(); - try { - // TODO: We should change the return type from List<Object> to List<Parcelable> - List<Object> info = mService.getShortcutInputMethodsAndSubtypes(); - // "info" has imi1, subtype1, subtype2, imi2, subtype2, imi3, subtype3..in the list - ArrayList<InputMethodSubtype> subtypes = null; - if (info != null && !info.isEmpty()) { - final int N = info.size(); - for (int i = 0; i < N; ++i) { - Object o = info.get(i); - if (o instanceof InputMethodInfo) { - if (ret.containsKey(o)) { - Log.e(TAG, "IMI list already contains the same InputMethod."); - break; - } - subtypes = new ArrayList<>(); - ret.put((InputMethodInfo)o, subtypes); - } else if (subtypes != null && o instanceof InputMethodSubtype) { - subtypes.add((InputMethodSubtype)o); - } - } + final List<InputMethodInfo> enabledImes = getEnabledInputMethodList(); + + // Ensure we check system IMEs first. + enabledImes.sort(Comparator.comparingInt(imi -> imi.isSystem() ? 0 : 1)); + + final int numEnabledImes = enabledImes.size(); + for (int imiIndex = 0; imiIndex < numEnabledImes; ++imiIndex) { + final InputMethodInfo imi = enabledImes.get(imiIndex); + final List<InputMethodSubtype> subtypes = getEnabledInputMethodSubtypeList( + imi, true); + final int subtypeCount = subtypes.size(); + for (int subtypeIndex = 0; subtypeIndex < subtypeCount; ++subtypeIndex) { + final InputMethodSubtype subtype = imi.getSubtypeAt(subtypeIndex); + if (SUBTYPE_MODE_VOICE.equals(subtype.getMode())) { + return Collections.singletonMap(imi, Collections.singletonList(subtype)); } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); } - return ret; } + return Collections.emptyMap(); } /** diff --git a/core/java/android/view/inputmethod/InputMethodSystemProperty.java b/core/java/android/view/inputmethod/InputMethodSystemProperty.java new file mode 100644 index 000000000000..b233b756686f --- /dev/null +++ b/core/java/android/view/inputmethod/InputMethodSystemProperty.java @@ -0,0 +1,74 @@ +/* + * 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 android.view.inputmethod; + +import android.annotation.Nullable; +import android.content.ComponentName; +import android.os.Build; +import android.os.SystemProperties; + +/** + * Various (pseudo) constants about IME behaviors. + * + * @hide + */ +public class InputMethodSystemProperty { + /** + * System property key for the production use. The value must be either empty or a valid + * (flattened) component name of the multi-client IME. + */ + private static final String PROP_PROD_MULTI_CLIENT_IME = "ro.sys.multi_client_ime"; + + /** + * System property key for debugging purpose. The value must be either empty or a valid + * (flattened) component name of the multi-client IME. + * + * <p>This value will be ignored when {@link Build#IS_DEBUGGABLE} returns {@code false}</p> + */ + private static final String PROP_DEBUG_MULTI_CLIENT_IME = "persist.debug.multi_client_ime"; + + @Nullable + private static ComponentName getMultiClientImeComponentName() { + if (Build.IS_DEBUGGABLE) { + // If debuggable, allow developers to override the multi-client IME component name + // with a different (writable) key. + final ComponentName debugIme = ComponentName.unflattenFromString( + SystemProperties.get(PROP_DEBUG_MULTI_CLIENT_IME, "")); + if (debugIme != null) { + return debugIme; + } + } + return ComponentName.unflattenFromString( + SystemProperties.get(PROP_PROD_MULTI_CLIENT_IME, "")); + } + + /** + * {@link ComponentName} of multi-client IME to be used. + * + * @hide + */ + @Nullable + public static final ComponentName sMultiClientImeComponentName = + getMultiClientImeComponentName(); + + /** + * {@code true} when multi-client IME is enabled. + * + * @hide + */ + public static final boolean MULTI_CLIENT_IME_ENABLED = (sMultiClientImeComponentName != null); +} diff --git a/core/java/android/webkit/ConsoleMessage.java b/core/java/android/webkit/ConsoleMessage.java index 6051956531e4..e54849772f9a 100644 --- a/core/java/android/webkit/ConsoleMessage.java +++ b/core/java/android/webkit/ConsoleMessage.java @@ -17,6 +17,7 @@ package android.webkit; import android.annotation.UnsupportedAppUsage; +import android.os.Build; /** * Public class representing a JavaScript console message from WebCore. This could be a issued @@ -36,13 +37,13 @@ public class ConsoleMessage { DEBUG }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private MessageLevel mLevel; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mMessage; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mSourceId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mLineNumber; public ConsoleMessage(String message, String sourceId, int lineNumber, MessageLevel msgLevel) { diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java index 03ff0ca63282..8a1a0b5ef9b0 100644 --- a/core/java/android/webkit/UserPackage.java +++ b/core/java/android/webkit/UserPackage.java @@ -34,7 +34,7 @@ public class UserPackage { private final UserInfo mUserInfo; private final PackageInfo mPackageInfo; - public static final int MINIMUM_SUPPORTED_SDK = Build.VERSION_CODES.P; + public static final int MINIMUM_SUPPORTED_SDK = Build.VERSION_CODES.Q; public UserPackage(UserInfo user, PackageInfo packageInfo) { this.mUserInfo = user; diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 414cb8f30fc7..bad2dbfebdc5 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -850,7 +850,7 @@ public class WebView extends AbsoluteLayout /** * Asynchronously evaluates JavaScript in the context of the currently displayed page. - * If non-null, |resultCallback| will be invoked with any result returned from that + * If non-null, {@code resultCallback} will be invoked with any result returned from that * execution. This method must be called on the UI thread and the callback will * be made on the UI thread. * <p> diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 46b1f6e6189e..6d88530f29d9 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -47,7 +47,7 @@ public final class WebViewFactory { // visible for WebViewZygoteInit to look up the class by reflection and call preloadInZygote. /** @hide */ private static final String CHROMIUM_WEBVIEW_FACTORY = - "com.android.webview.chromium.WebViewChromiumFactoryProviderForP"; + "com.android.webview.chromium.WebViewChromiumFactoryProviderForQ"; private static final String CHROMIUM_WEBVIEW_FACTORY_METHOD = "create"; diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 07096e815d15..99895bd65398 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -29,6 +29,7 @@ import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.TransitionDrawable; +import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -316,7 +317,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * The drawable used to draw the selector */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) Drawable mSelector; /** @@ -677,7 +678,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * ID of the active pointer. This is used to retain consistency during * drags/flings if multiple pointers are used. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mActivePointerId = INVALID_POINTER; /** @@ -6571,7 +6572,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @ViewDebug.IntToString(from = ITEM_VIEW_TYPE_IGNORE, to = "ITEM_VIEW_TYPE_IGNORE"), @ViewDebug.IntToString(from = ITEM_VIEW_TYPE_HEADER_OR_FOOTER, to = "ITEM_VIEW_TYPE_HEADER_OR_FOOTER") }) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int viewType; /** diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index ea1bfc2854c2..d6a0ae48cc13 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -22,6 +22,7 @@ import android.annotation.Widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; +import android.os.Build; import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; @@ -105,7 +106,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList /** * Helper for detecting touch gestures. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private GestureDetector mGestureDetector; /** @@ -149,7 +150,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList /** * The currently selected item's child. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private View mSelectedChild; /** @@ -480,7 +481,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList /** * @return The center of this Gallery. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int getCenterOfGallery() { return (getWidth() - mPaddingLeft - mPaddingRight) / 2 + mPaddingLeft; } @@ -488,7 +489,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList /** * @return The center of the given view. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static int getCenterOfView(View view) { return view.getLeft() + view.getWidth() / 2; } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index ee04bcfddb27..9b497866486d 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -28,6 +28,7 @@ import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.os.Trace; import android.util.AttributeSet; @@ -189,7 +190,7 @@ public class ListView extends AbsListView { @UnsupportedAppUsage Drawable mDivider; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mDividerHeight; Drawable mOverScrollHeader; @@ -1390,7 +1391,7 @@ public class ListView extends AbsListView { * startPosition is 0). * @return The height of this ListView with the given children. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) final int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition, int maxHeight, int disallowPartialChildPosition) { final ListAdapter adapter = mAdapter; @@ -1533,7 +1534,7 @@ public class ListView extends AbsListView { * * @param childCount Number of children */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private void correctTooHigh(int childCount) { // First see if the last item is visible. If it is not, it is OK for the // top of the list to be pushed up. @@ -1583,7 +1584,7 @@ public class ListView extends AbsListView { * * @param childCount Number of children */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private void correctTooLow(int childCount) { // First see if the first item is visible. If it is not, it is OK for the // bottom of the list to be pushed down. diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java index 82d77c528564..65925b446bbe 100644 --- a/core/java/android/widget/MediaController.java +++ b/core/java/android/widget/MediaController.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.PixelFormat; import android.media.AudioManager; +import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; @@ -87,9 +88,9 @@ public class MediaController extends FrameLayout { private WindowManager.LayoutParams mDecorLayoutParams; @UnsupportedAppUsage private ProgressBar mProgress; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private TextView mEndTime; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private TextView mCurrentTime; @UnsupportedAppUsage private boolean mShowing; @@ -107,9 +108,9 @@ public class MediaController extends FrameLayout { private ImageButton mFfwdButton; @UnsupportedAppUsage private ImageButton mRewButton; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private ImageButton mNextButton; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private ImageButton mPrevButton; private CharSequence mPlayDescription; private CharSequence mPauseDescription; diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 18838090f58b..ed6f0d6bcba3 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -206,9 +206,9 @@ public class PopupWindow { private float mElevation; private Drawable mBackground; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private Drawable mAboveAnchorBackgroundDrawable; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private Drawable mBelowAnchorBackgroundDrawable; private Transition mEnterTransition; diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java index a27354dc2bac..15e1ffa7bc31 100644 --- a/core/java/android/widget/SimpleAdapter.java +++ b/core/java/android/widget/SimpleAdapter.java @@ -22,6 +22,7 @@ import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.net.Uri; +import android.os.Build; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; @@ -59,7 +60,7 @@ public class SimpleAdapter extends BaseAdapter implements Filterable, ThemedSpin private String[] mFrom; private ViewBinder mViewBinder; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private List<? extends Map<String, ?>> mData; private int mResource; diff --git a/core/java/android/widget/SimpleCursorAdapter.java b/core/java/android/widget/SimpleCursorAdapter.java index b670e6c83f9d..77fe5d1a9302 100644 --- a/core/java/android/widget/SimpleCursorAdapter.java +++ b/core/java/android/widget/SimpleCursorAdapter.java @@ -20,6 +20,7 @@ import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.view.View; /** @@ -52,7 +53,7 @@ public class SimpleCursorAdapter extends ResourceCursorAdapter { * This field should be made private, so it is hidden from the SDK. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) protected int[] mFrom; /** * A list of View ids representing the views to which the data must be bound. diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b5cdedc4ea80..0ea8579fafe6 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -429,7 +429,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @ViewDebug.ExportedProperty(category = "text") @UnsupportedAppUsage private int mCurTextColor; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCurHintTextColor; private boolean mFreezesText; @@ -10013,7 +10013,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener && mSavedMarqueeModeLayout.getLineWidth(0) > width)); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private void startMarquee() { // Do not ellipsize EditText if (getKeyListener() != null) return; @@ -10056,7 +10056,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private void startStopMarquee(boolean start) { if (mEllipsize == TextUtils.TruncateAt.MARQUEE) { if (start) { diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java index 8b45d997627a..40b0f13c596b 100644 --- a/core/java/android/widget/VideoView.java +++ b/core/java/android/widget/VideoView.java @@ -113,7 +113,7 @@ public class VideoView extends SurfaceView private int mTargetState = STATE_IDLE; // All the stuff we need for playing and showing a video - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private SurfaceHolder mSurfaceHolder = null; @UnsupportedAppUsage private MediaPlayer mMediaPlayer = null; @@ -565,7 +565,7 @@ public class VideoView extends SurfaceView } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener() { public boolean onError(MediaPlayer mp, int framework_err, int impl_err) { diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index ef5eb6cb5780..a50c736e195e 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -101,6 +101,7 @@ public class ResolverActivity extends Activity { private AbsListView mAdapterView; private Button mAlwaysButton; private Button mOnceButton; + private Button mSettingsButton; private View mProfileView; private int mIconDpi; private int mLastSelected = AbsListView.INVALID_POSITION; @@ -112,6 +113,7 @@ public class ResolverActivity extends Activity { private String mReferrerPackage; private CharSequence mTitle; private int mDefaultTitleResId; + private boolean mUseLayoutForBrowsables; // Whether or not this activity supports choosing a default handler for the intent. private boolean mSupportsAlwaysUseOption; @@ -192,6 +194,12 @@ public class ResolverActivity extends Activity { com.android.internal.R.string.whichHomeApplicationNamed, com.android.internal.R.string.whichHomeApplicationLabel); + // SpR.id.buttonecial titles for BROWSABLE components + public static final int BROWSABLE_TITLE_RES = + com.android.internal.R.string.whichGiveAccessToApplication; + public static final int BROWSABLE_NAMED_TITLE_RES = + com.android.internal.R.string.whichGiveAccessToApplicationNamed; + public final String action; public final int titleRes; public final int namedTitleRes; @@ -283,7 +291,6 @@ public class ResolverActivity extends Activity { mPackageMonitor.register(this, getMainLooper(), false); mRegistered = true; mReferrerPackage = getReferrerPackageName(); - mSupportsAlwaysUseOption = supportsAlwaysUseOption; final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); mIconDpi = am.getLauncherLargeIconDensity(); @@ -293,6 +300,14 @@ public class ResolverActivity extends Activity { mTitle = title; mDefaultTitleResId = defaultTitleRes; + mUseLayoutForBrowsables = getTargetIntent() == null + ? false + : getTargetIntent().hasCategory(Intent.CATEGORY_BROWSABLE); + + // We don't want to support Always Use if browsable layout is being used, + // as to mitigate Intent Capturing vulnerability + mSupportsAlwaysUseOption = supportsAlwaysUseOption && !mUseLayoutForBrowsables; + mIconFactory = IconDrawableFactory.newInstance(this, true); if (configureContentView(mIntents, initialIntents, rList)) { return; @@ -448,13 +463,23 @@ public class ResolverActivity extends Activity { mSafeForwardingMode = safeForwarding; } - protected CharSequence getTitleForAction(String action, int defaultTitleRes) { - final ActionTitle title = mResolvingHome ? ActionTitle.HOME : ActionTitle.forAction(action); + protected CharSequence getTitleForAction(Intent intent, int defaultTitleRes) { + final ActionTitle title = mResolvingHome + ? ActionTitle.HOME + : ActionTitle.forAction(intent.getAction()); + // While there may already be a filtered item, we can only use it in the title if the list // is already sorted and all information relevant to it is already in the list. final boolean named = mAdapter.getFilteredPosition() >= 0; if (title == ActionTitle.DEFAULT && defaultTitleRes != 0) { return getString(defaultTitleRes); + } else if (intent.hasCategory(Intent.CATEGORY_BROWSABLE)) { + // If the Intent is BROWSABLE then we need to warn the user that + // they're giving access for the activity to open URLs from this specific host + return named + ? getString(ActionTitle.BROWSABLE_NAMED_TITLE_RES, intent.getData().getHost(), + mAdapter.getFilteredItem().getDisplayLabel()) + : getString(ActionTitle.BROWSABLE_TITLE_RES, intent.getData().getHost()); } else { return named ? getString(title.namedTitleRes, mAdapter.getFilteredItem().getDisplayLabel()) @@ -555,7 +580,7 @@ public class ResolverActivity extends Activity { @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); - resetAlwaysOrOnceButtonBar(); + resetButtonBar(); } private boolean hasManagedProfile() { @@ -607,11 +632,23 @@ public class ResolverActivity extends Activity { public void onButtonClick(View v) { final int id = v.getId(); - startSelected(mAdapter.hasFilteredItem() ? - mAdapter.getFilteredPosition(): - mAdapterView.getCheckedItemPosition(), - id == R.id.button_always, - !mAdapter.hasFilteredItem()); + int which = mAdapter.hasFilteredItem() + ? mAdapter.getFilteredPosition() + : mAdapterView.getCheckedItemPosition(); + boolean hasIndexBeenFiltered = !mAdapter.hasFilteredItem(); + if (id == R.id.button_app_settings) { + showSettingsForSelected(which, hasIndexBeenFiltered); + } else { + startSelected(which, id == R.id.button_always, hasIndexBeenFiltered); + } + } + + private void showSettingsForSelected(int which, boolean hasIndexBeenFiltered) { + ResolveInfo ri = mAdapter.resolveInfoForPosition(which, hasIndexBeenFiltered); + Intent in = new Intent().setAction(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS) + .setData(Uri.fromParts("package", ri.activityInfo.packageName, null)) + .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + startActivity(in); } public void startSelected(int which, boolean always, boolean hasIndexBeenFiltered) { @@ -995,7 +1032,7 @@ public class ResolverActivity extends Activity { adapterView.setOnItemClickListener(listener); adapterView.setOnItemLongClickListener(listener); - if (mSupportsAlwaysUseOption) { + if (mSupportsAlwaysUseOption || mUseLayoutForBrowsables) { listView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); } @@ -1017,7 +1054,7 @@ public class ResolverActivity extends Activity { CharSequence title = mTitle != null ? mTitle - : getTitleForAction(getTargetIntent().getAction(), mDefaultTitleResId); + : getTitleForAction(getTargetIntent(), mDefaultTitleResId); if (!TextUtils.isEmpty(title)) { final TextView titleView = findViewById(R.id.title); @@ -1051,16 +1088,47 @@ public class ResolverActivity extends Activity { } } - public void resetAlwaysOrOnceButtonBar() { - if (mSupportsAlwaysUseOption) { - final ViewGroup buttonLayout = findViewById(R.id.button_bar); - if (buttonLayout != null) { - buttonLayout.setVisibility(View.VISIBLE); - mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always); - mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once); + private void resetButtonBar() { + if (!mSupportsAlwaysUseOption && !mUseLayoutForBrowsables) { + return; + } + final ViewGroup buttonLayout = findViewById(R.id.button_bar); + if (buttonLayout != null) { + buttonLayout.setVisibility(View.VISIBLE); + mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once); + mSettingsButton = (Button) buttonLayout.findViewById(R.id.button_app_settings); + mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always); + + if (mUseLayoutForBrowsables) { + resetSettingsOrOnceButtonBar(); } else { - Log.e(TAG, "Layout unexpectedly does not have a button bar"); + resetAlwaysOrOnceButtonBar(); } + } else { + Log.e(TAG, "Layout unexpectedly does not have a button bar"); + } + } + + private void resetSettingsOrOnceButtonBar() { + //unsetting always button + mAlwaysButton.setVisibility(View.GONE); + + // When the items load in, if an item was already selected, + // enable the buttons + if (mAdapterView != null + && mAdapterView.getCheckedItemPosition() != ListView.INVALID_POSITION) { + mSettingsButton.setEnabled(true); + mOnceButton.setEnabled(true); + } + } + + private void resetAlwaysOrOnceButtonBar() { + // This check needs to be made because layout with default + // doesn't have a settings button + if (mSettingsButton != null) { + //unsetting always button + mSettingsButton.setVisibility(View.GONE); + mSettingsButton = null; } if (useLayoutWithDefault() @@ -1625,7 +1693,7 @@ public class ResolverActivity extends Activity { @Override public void run() { setTitleAndIcon(); - resetAlwaysOrOnceButtonBar(); + resetButtonBar(); onListRebuilt(); mPostListReadyRunnable = null; } @@ -1986,8 +2054,14 @@ public class ResolverActivity extends Activity { final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION; if (!useLayoutWithDefault() && (!hasValidSelection || mLastSelected != checkedPos) - && mAlwaysButton != null) { - setAlwaysButtonEnabled(hasValidSelection, checkedPos, true); + && (mAlwaysButton != null || mSettingsButton != null)) { + if (mSettingsButton != null) { + // this implies that the layout for browsables is being used + mSettingsButton.setEnabled(true); + } else { + // this implies that mAlwaysButton != null + setAlwaysButtonEnabled(hasValidSelection, checkedPos, true); + } mOnceButton.setEnabled(hasValidSelection); if (hasValidSelection) { mAdapterView.smoothScrollToPosition(checkedPos); diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java index d4c451e3ffff..78d366cd2436 100644 --- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java +++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java @@ -68,10 +68,10 @@ public class AmbientDisplayConfiguration { public boolean wakeLockScreenGestureEnabled(int user) { return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, user) - && wakeLockScreenGestureAvailable(); + && wakeScreenGestureAvailable(); } - public boolean wakeLockScreenGestureAvailable() { + public boolean wakeScreenGestureAvailable() { return mContext.getResources() .getBoolean(R.bool.config_dozeWakeLockScreenSensorAvailable); } @@ -81,10 +81,6 @@ public class AmbientDisplayConfiguration { && wakeScreenGestureAvailable(); } - public boolean wakeScreenGestureAvailable() { - return !TextUtils.isEmpty(wakeScreenSensorType()); - } - public String doubleTapSensorType() { return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType); } @@ -93,10 +89,6 @@ public class AmbientDisplayConfiguration { return mContext.getResources().getString(R.string.config_dozeLongPressSensorType); } - public String wakeScreenSensorType() { - return mContext.getResources().getString(R.string.config_dozeWakeScreenSensorType); - } - public boolean pulseOnLongPressEnabled(int user) { return pulseOnLongPressAvailable() && boolSettingDefaultOff( Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, user); diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java index 33918400d571..c94c64a879b3 100644 --- a/core/java/com/android/internal/infra/AbstractRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractRemoteService.java @@ -33,6 +33,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.util.Slog; +import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; @@ -62,7 +63,10 @@ import java.lang.ref.WeakReference; //TODO(b/117779333): improve javadoc above instead of using Autofill as an example public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I>, I extends IInterface> implements DeathRecipient { - private static final int MSG_UNBIND = 1; + private static final int MSG_BIND = 1; + private static final int MSG_UNBIND = 2; + + protected static final long PERMANENT_BOUND_TIMEOUT_MS = 0; protected static final int LAST_PRIVATE_MSG = MSG_UNBIND; @@ -86,6 +90,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I private boolean mServiceDied; private boolean mCompleted; + // Used just for debugging purposes (on dump) + private long mNextUnbind; + /** * Callback called when the service dies. * @@ -100,7 +107,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I void onServiceDied(T service); } - // NOTE: must be package-protected so this class is not extend outside + // NOTE: must be package-protected so this class is not extended outside AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId, @NonNull VultureCallback<S> callback, boolean bindInstantServiceAllowed, boolean verbose) { @@ -156,7 +163,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I protected abstract I getServiceInterface(@NonNull IBinder service); /** - * Defines How long after the last interaction with the service we would unbind. + * Defines how long after the last interaction with the service we would unbind. + * + * @return time to unbind (in millis), or {@link #PERMANENT_BOUND_TIMEOUT_MS} to not unbind. */ protected abstract long getTimeoutIdleBindMillis(); @@ -220,11 +229,23 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I .append(mComponentName.flattenToString()).println(); pw.append(prefix).append(tab).append("destroyed=") .append(String.valueOf(mDestroyed)).println(); + final boolean bound = handleIsBound(); pw.append(prefix).append(tab).append("bound=") - .append(String.valueOf(handleIsBound())).println(); + .append(String.valueOf(bound)); + final long idleTimeout = getTimeoutIdleBindMillis(); + if (bound) { + if (idleTimeout > 0) { + pw.append(" (unbind in : "); + TimeUtils.formatDuration(mNextUnbind - SystemClock.elapsedRealtime(), pw); + pw.append(")"); + } else { + pw.append(" (permanently bound)"); + } + } + pw.println(); pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed); pw.append(prefix).append("idleTimeout=") - .append(Long.toString(getTimeoutIdleBindMillis() / 1000)).append("s").println(); + .append(Long.toString(idleTimeout / 1000)).append("s").println(); pw.append(prefix).append("requestTimeout=") .append(Long.toString(getRemoteRequestMillis() / 1000)).append("s").println(); pw.println(); @@ -236,6 +257,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I * <p>This request must be responded by the service somehow (typically using a callback), * othewise it will trigger a {@link PendingRequest#onTimeout(AbstractRemoteService)} if the * service doesn't respond. + * + * <p><b>NOTE: </b>this request is responsible for calling {@link #scheduleUnbind()}. */ protected void scheduleRequest(@NonNull PendingRequest<S, I> pendingRequest) { cancelScheduledUnbind(); @@ -250,7 +273,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I * a simple {@link Runnable}. */ protected void scheduleAsyncRequest(@NonNull AsyncRequest<I> request) { - cancelScheduledUnbind(); + scheduleUnbind(); // TODO(b/117779333): fix generics below @SuppressWarnings({"unchecked", "rawtypes"}) final MyAsyncPendingRequest<S, I> asyncRequest = new MyAsyncPendingRequest(this, request); @@ -262,13 +285,41 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I mHandler.removeMessages(MSG_UNBIND); } + /** + * Schedules a request to bind to the remote service. + * + * <p>Typically used on constructor for implementations that need a permanent connection to + * the remote service. + */ + protected void scheduleBind() { + if (mHandler.hasMessages(MSG_BIND)) { + if (mVerbose) Slog.v(mTag, "scheduleBind(): already scheduled"); + return; + } + mHandler.sendMessage(obtainMessage(AbstractRemoteService::handleEnsureBound, this) + .setWhat(MSG_BIND)); + } + + /** + * Schedules a request to automatically unbind from the service after the + * {@link #getTimeoutIdleBindMillis() idle timeout} expires. + */ protected void scheduleUnbind() { + final long unbindDelay = getTimeoutIdleBindMillis(); + + if (unbindDelay <= 0) { + if (mVerbose) Slog.v(mTag, "not scheduling unbind when value is " + unbindDelay); + return; + } + cancelScheduledUnbind(); - // TODO(b/111276913): implement "permanent binding" // TODO(b/117779333): make sure it's unbound if the service settings changing (right now // it's not) + + mNextUnbind = SystemClock.elapsedRealtime() + unbindDelay; + if (mVerbose) Slog.v(mTag, "unbinding in " + unbindDelay + "ms: " + mNextUnbind); mHandler.sendMessageDelayed(obtainMessage(AbstractRemoteService::handleUnbind, this) - .setWhat(MSG_UNBIND), getTimeoutIdleBindMillis()); + .setWhat(MSG_UNBIND), unbindDelay); } private void handleUnbind() { @@ -342,6 +393,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I mService = null; } } + mNextUnbind = 0; mContext.unbindService(mServiceConnection); } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index bc4b5fe3ff17..ec02432223de 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -17,6 +17,7 @@ package com.android.internal.net; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -52,7 +53,7 @@ public class VpnProfile implements Cloneable, Parcelable { public String name = ""; // 0 @UnsupportedAppUsage public int type = TYPE_PPTP; // 1 - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String server = ""; // 2 @UnsupportedAppUsage public String username = ""; // 3 diff --git a/core/java/com/android/internal/os/AtomicFile.java b/core/java/com/android/internal/os/AtomicFile.java index e177fe303253..a72a2f5e1be3 100644 --- a/core/java/com/android/internal/os/AtomicFile.java +++ b/core/java/com/android/internal/os/AtomicFile.java @@ -17,6 +17,7 @@ package com.android.internal.os; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.FileUtils; import android.util.Log; @@ -51,7 +52,7 @@ public final class AtomicFile { mBackupName = new File(baseName.getPath() + ".bak"); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public File getBaseFile() { return mBaseName; } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 017da550c9d3..cc8da5c6317f 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -5970,7 +5970,6 @@ public class BatteryStatsImpl extends BatteryStats { } else { stopAllWifiSignalStrengthTimersLocked(-1); } - StatsLog.write(StatsLog.WIFI_SIGNAL_STRENGTH_CHANGED, strengthBin); mWifiSignalStrengthBin = strengthBin; } } @@ -6138,8 +6137,6 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<N; i++) { final int uid = mapUid(ws.get(i)); noteWifiScanStartedLocked(uid); - StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i), - StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6148,8 +6145,6 @@ public class BatteryStatsImpl extends BatteryStats { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); noteWifiScanStartedLocked(uid); - StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, workChain.getUids(), - workChain.getTags(), StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON); } } } @@ -6159,8 +6154,6 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<N; i++) { final int uid = mapUid(ws.get(i)); noteWifiScanStoppedLocked(uid); - StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i), - StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6169,9 +6162,6 @@ public class BatteryStatsImpl extends BatteryStats { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); noteWifiScanStoppedLocked(uid); - StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, - workChain.getUids(), workChain.getTags(), - StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF); } } } @@ -7190,9 +7180,6 @@ public class BatteryStatsImpl extends BatteryStats { WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); } mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); - StatsLog.write_non_chained( - StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null, - StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__ON); } mWifiMulticastWakelockCount++; } @@ -7206,9 +7193,6 @@ public class BatteryStatsImpl extends BatteryStats { mWifiMulticastWakelockCount--; if (mWifiMulticastWakelockCount == 0) { mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); - StatsLog.write_non_chained( - StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null, - StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__OFF); } } diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java index 69297b5582a5..b0888f2c8df9 100644 --- a/core/java/com/android/internal/util/AsyncChannel.java +++ b/core/java/com/android/internal/util/AsyncChannel.java @@ -21,6 +21,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -162,7 +163,7 @@ public class AsyncChannel { sCmdToString[CMD_CHANNEL_DISCONNECT - BASE] = "CMD_CHANNEL_DISCONNECT"; sCmdToString[CMD_CHANNEL_DISCONNECTED - BASE] = "CMD_CHANNEL_DISCONNECTED"; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) protected static String cmdToString(int cmd) { cmd -= BASE; if ((cmd >= 0) && (cmd < sCmdToString.length)) { @@ -591,7 +592,7 @@ public class AsyncChannel { * @param srcMsg * @param what */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void replyToMessage(Message srcMsg, int what) { Message msg = Message.obtain(); msg.what = what; diff --git a/core/java/com/android/internal/util/JournaledFile.java b/core/java/com/android/internal/util/JournaledFile.java index 258db2a1fc48..065cc5b2416b 100644 --- a/core/java/com/android/internal/util/JournaledFile.java +++ b/core/java/com/android/internal/util/JournaledFile.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.File; import java.io.IOException; @@ -47,7 +48,7 @@ public class JournaledFile { * it to the real one. If there is both a real file and a temp one, assumes that the * temp one isn't fully written and deletes it. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public File chooseForRead() { File result; if (mReal.exists()) { @@ -72,7 +73,7 @@ public class JournaledFile { * <p> * Call {@link #commit} to commit the changes, or {@link #rollback} to forget the changes. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public File chooseForWrite() { if (mWriting) { throw new IllegalStateException("uncommitted write already in progress"); @@ -100,7 +101,7 @@ public class JournaledFile { /** * Commit changes. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void commit() { if (!mWriting) { throw new IllegalStateException("no file to commit"); @@ -112,7 +113,7 @@ public class JournaledFile { /** * Roll back changes. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void rollback() { if (!mWriting) { throw new IllegalStateException("no file to roll back"); diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index f62c4402cb4e..70f4ed2d529e 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -42,9 +42,6 @@ interface IInputMethodManager { List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId, boolean allowsImplicitlySelectedSubtypes); InputMethodSubtype getLastInputMethodSubtype(); - // TODO: We should change the return type from List to List<Parcelable> - // Currently there is a bug that aidl doesn't accept List<Parcelable> - List getShortcutInputMethodsAndSubtypes(); boolean showSoftInput(in IInputMethodClient client, int flags, in ResultReceiver resultReceiver); @@ -68,10 +65,6 @@ interface IInputMethodManager { int displayId); void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId); boolean isInputMethodPickerShownForTest(); - // TODO(Bug 114488811): this can be removed once we deprecate special null token rule. - void setInputMethod(in IBinder token, String id); - // TODO(Bug 114488811): this can be removed once we deprecate special null token rule. - void setInputMethodAndSubtype(in IBinder token, String id, in InputMethodSubtype subtype); void registerSuggestionSpansForNotification(in SuggestionSpan[] spans); boolean notifySuggestionPicked(in SuggestionSpan span, String originalString, int index); InputMethodSubtype getCurrentInputMethodSubtype(); diff --git a/core/jni/android/graphics/text/LineBreaker.cpp b/core/jni/android/graphics/text/LineBreaker.cpp index e1f2f2b8e069..c23f1e956cd4 100644 --- a/core/jni/android/graphics/text/LineBreaker.cpp +++ b/core/jni/android/graphics/text/LineBreaker.cpp @@ -16,8 +16,6 @@ #define LOG_TAG "LineBreaker" -#include "unicode/locid.h" -#include "unicode/brkiter.h" #include "utils/misc.h" #include "utils/Log.h" #include <nativehelper/ScopedStringChars.h> diff --git a/core/jni/android/graphics/text/MeasuredText.cpp b/core/jni/android/graphics/text/MeasuredText.cpp index d7d96fbf3956..68ba38b93915 100644 --- a/core/jni/android/graphics/text/MeasuredText.cpp +++ b/core/jni/android/graphics/text/MeasuredText.cpp @@ -17,8 +17,6 @@ #define LOG_TAG "MeasuredText" #include "GraphicsJNI.h" -#include "unicode/locid.h" -#include "unicode/brkiter.h" #include "utils/misc.h" #include "utils/Log.h" #include <nativehelper/ScopedStringChars.h> diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 29d8f30543e6..80560f826235 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -1906,6 +1906,53 @@ exit: return jStatus; } +static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz, + jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) { + if (deviceTypes == nullptr || deviceAddresses == nullptr) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + jsize nb = env->GetArrayLength(deviceTypes); + if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + // retrieve all device types + std::vector<audio_devices_t> deviceTypesVector; + jint* typesPtr = nullptr; + typesPtr = env->GetIntArrayElements(deviceTypes, 0); + if (typesPtr == nullptr) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + for (jint i = 0; i < nb; i++) { + deviceTypesVector.push_back((audio_devices_t) typesPtr[i]); + } + env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0); + + // check each address is a string and add device type/address to list for device affinity + Vector<AudioDeviceTypeAddr> deviceVector; + jclass stringClass = FindClassOrDie(env, "java/lang/String"); + for (jint i = 0; i < nb; i++) { + jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i); + if (!env->IsInstanceOf(addrJobj, stringClass)) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + String8 address = String8(env->GetStringUTFChars((jstring) addrJobj, NULL)); + AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address); + deviceVector.add(dev); + } + + status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector); + return (jint) nativeToJavaStatus(status); +} + +static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, jobject clazz, + jint uid) { + + //### + status_t status = NO_ERROR;//AudioSystem::removeUidDeviceAffinities(); + return (jint) nativeToJavaStatus(status); +} + + static jint android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz) { @@ -2133,6 +2180,10 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_getAudioHwSyncForSession}, {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I", (void *)android_media_AudioSystem_registerPolicyMixes}, + {"setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I", + (void *)android_media_AudioSystem_setUidDeviceAffinities}, + {"removeUidDeviceAffinities", "(I)I", + (void *)android_media_AudioSystem_removeUidDeviceAffinities}, {"native_register_dynamic_policy_callback", "()V", (void *)android_media_AudioSystem_registerDynPolicyCallback}, {"native_register_recording_callback", "()V", diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index ff4591fb7f45..a8e142784397 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1119,6 +1119,13 @@ static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gi capabilities |= (1LL << CAP_SYS_NICE); } + if (multiuser_get_app_id(uid) == AID_NETWORK_STACK) { + capabilities |= (1LL << CAP_NET_ADMIN); + capabilities |= (1LL << CAP_NET_BROADCAST); + capabilities |= (1LL << CAP_NET_BIND_SERVICE); + capabilities |= (1LL << CAP_NET_RAW); + } + /* * Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock" */ diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index 60561bd9dbc5..6f9a5649d4ac 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -82,6 +82,7 @@ message ActivityDisplayProto { repeated ActivityStackProto stacks = 3; optional int32 focused_stack_id = 4; optional .com.android.server.wm.IdentifierProto resumed_activity = 5; + optional bool single_task_instance = 6; } message ActivityStackProto { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 299798bde7d3..b16c16d0a703 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -42,6 +42,8 @@ <protected-broadcast android:name="android.intent.action.PACKAGE_REMOVED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_REMOVED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_CHANGED" /> + <protected-broadcast android:name="android.intent.action.PACKAGE_ENABLE_ROLLBACK" /> + <protected-broadcast android:name="android.intent.action.PACKAGE_ROLLBACK_EXECUTED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_RESTARTED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_DATA_CLEARED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" /> @@ -611,6 +613,7 @@ <protected-broadcast android:name="android.intent.action.DOCK_ACTIVE" /> <!-- Added in Q --> + <protected-broadcast android:name="android.content.pm.action.SESSION_UPDATED" /> <!-- For CarIdlenessTracker --> <protected-broadcast android:name="com.android.server.jobscheduler.GARAGE_MODE_ON" /> @@ -3845,6 +3848,12 @@ <permission android:name="android.permission.BIND_PACKAGE_VERIFIER" android:protectionLevel="signature" /> + <!-- @hide Rollback manager needs to have this permission before the PackageManager will + trust it to enable rollback. + --> + <permission android:name="android.permission.PACKAGE_ROLLBACK_AGENT" + android:protectionLevel="signature" /> + <!-- @SystemApi @hide Allows an application to mark other applications as harmful --> <permission android:name="android.permission.SET_HARMFUL_APP_WARNINGS" android:protectionLevel="signature|verifier" /> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_0_bars.xml b/core/res/res/drawable/ic_signal_wifi_badged_0_bars.xml deleted file mode 100644 index 606b686bd59b..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_0_bars.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-377 308.5c0 -2.5 2 -4.5 4.5 -4.5l3.5 0 0.79999 -1c-0.29999 -0.29999 -3.70001 -3 -8.79999 -3 -5.09998 0 -8.5 2.79999 -8.79999 3l8.79999 11 0 0 0 0 1.60001 -2c-0.9 -0.89999 -1.60001 -2.10001 -1.60001 -3.5z" - android:fillColor="#FFFFFF" - android:fillAlpha="0.3" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_1_bar.xml b/core/res/res/drawable/ic_signal_wifi_badged_1_bar.xml deleted file mode 100644 index a4c5bc290d90..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_1_bar.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-377 308.5c0 -2.5 2 -4.5 4.5 -4.5l3.5 0 0.79999 -1c-0.29999 -0.29999 -3.70001 -3 -8.79999 -3 -5.09998 0 -8.5 2.79999 -8.79999 3l8.79999 11 0 0 0 0 1.60001 -2c-0.9 -0.89999 -1.60001 -2.10001 -1.60001 -3.5z" - android:fillColor="#FFFFFF" - android:fillAlpha="0.3" /> - <path - android:pathData="M-377 308.5c0 -0.20001 0 -0.29999 0.10001 -0.5 0 0 0 0 -0.10001 0 -2.10001 0 -3.60001 1.20001 -3.79999 1.29999L-377 314l1.60001 -2.10001c-0.9 -0.79998 -1.60001 -2 -1.60001 -3.39999z" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_2_bars.xml b/core/res/res/drawable/ic_signal_wifi_badged_2_bars.xml deleted file mode 100644 index 9c27833ed4e5..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_2_bars.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-377 308.5c0 -2.5 2 -4.5 4.5 -4.5l3.5 0 0.79999 -1c-0.29999 -0.29999 -3.70001 -3 -8.79999 -3 -5.09998 0 -8.5 2.79999 -8.79999 3l8.79999 11 0 0 0 0 1.60001 -2c-0.9 -0.89999 -1.60001 -2.10001 -1.60001 -3.5z" - android:fillColor="#FFFFFF" - android:fillAlpha="0.3" /> - <path - android:pathData="M-377 308.5c0 -0.89999 0.29999 -1.70001 0.70001 -2.5 -0.20001 0 -0.5 0 -0.70001 0 -2.79999 0 -4.79999 1.60001 -5 1.79999l5 6.20001 0 0 0 0 1.60001 -2c-1 -0.89999 -1.60001 -2.10001 -1.60001 -3.5z" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_3_bars.xml b/core/res/res/drawable/ic_signal_wifi_badged_3_bars.xml deleted file mode 100644 index 6d693f1cc94a..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_3_bars.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-377 308.5c0 -2.5 2 -4.5 4.5 -4.5l3.5 0 0.79999 -1c-0.29999 -0.29999 -3.70001 -3 -8.79999 -3 -5.09998 0 -8.5 2.79999 -8.79999 3l8.79999 11 0 0 0 0 1.60001 -2c-0.9 -0.89999 -1.60001 -2.10001 -1.60001 -3.5z" - android:fillColor="#FFFFFF" - android:fillAlpha="0.3" /> - <path - android:pathData="M-375.39999 311.89999c-1 -0.79998 -1.60001 -2.1 -1.60001 -3.39999 0 -1.79999 1.10001 -3.39999 2.70001 -4.10001C-375.09998 304.19998 -376 304 -377 304c-3.60001 0 -6 1.89999 -6.29999 2.20001L-377 314l0 0 0 0" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_4_bars.xml b/core/res/res/drawable/ic_signal_wifi_badged_4_bars.xml deleted file mode 100644 index c48fa364b1e6..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_4_bars.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-377 308.5c0 -2.5 2 -4.5 4.5 -4.5l3.5 0 0.79999 -1c-0.29999 -0.29999 -3.70001 -3 -8.79999 -3 -5.09998 0 -8.5 2.79999 -8.79999 3l8.79999 11 0 0 0 0 1.60001 -2c-0.9 -0.89999 -1.60001 -2.10001 -1.60001 -3.5z" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_4k.xml b/core/res/res/drawable/ic_signal_wifi_badged_4k.xml deleted file mode 100644 index 0868845bee92..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_4k.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-373.04999 308.79999l0.5 0 0 0.89999 -0.5 0 0 1.20001 -1.1 0 0 -1.20001 -1.9 0 -0.1 -0.70001 1.89999 -3.70001 1.10001 0 0 3.50003 0.1 0zm-1.89999 0l0.89999 0 0 -1.9 0 0 -0.89999 1.9z" - android:fillColor="#FFFFFF" /> - <path - android:pathData="M-370.44998 308.70001l-0.5 0.60001 0 1.70001 -1.10001 0 0 -5.70001 1.10001 0 0 2.5 0.39999 -0.60001 1.10001 -1.89999 1.39999 0 -1.6 2.5 1.70001 3.20001 -1.29999 0 -1.20001 -2.30002z" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_hd.xml b/core/res/res/drawable/ic_signal_wifi_badged_hd.xml deleted file mode 100644 index 657f5edf751c..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_hd.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-371.79999 311l-1.1 0 0 -2.29999 -0.79999 0 0 2.29999 -1.10001 0 0 -5.70001 1.10001 0 0 2.39999 0.79999 0 0 -2.39999 1.1 0 0 5.70001z" - android:fillColor="#FFFFFF" /> - <path - android:pathData="M-371.33557 310.98651l0 -5.68701 1.39068 0c0.27848 0 0.53336 0.0532 0.76465 0.16016 0.2313 0.10693 0.42954 0.2622 0.59568 0.46679 0.16519 0.20459 0.29357 0.45557 0.38421 0.75391 0.0906 0.29834 0.13593 0.63867 0.13593 1.02148l0 0.88672c0 0.38281 -0.0453 0.72363 -0.13593 1.021 -0.0906 0.29785 -0.21902 0.5498 -0.38421 0.7539 -0.16614 0.20411 -0.36628 0.35938 -0.59946 0.46485 -0.23316 0.10547 -0.49182 0.1582 -0.77786 0.1582l-1.37369 0zm1.06879 -4.76904l0 3.85107 0.26333 0c0.15491 0 0.28452 -0.0283 0.38971 -0.084 0.10516 -0.0557 0.19077 -0.14356 0.25681 -0.26367 0.066 -0.12012 0.11331 -0.27198 0.14184 -0.4585 0.0285 -0.18652 0.0424 -0.41113 0.0424 -0.67383l0 -0.89453c0 -0.26562 -0.0138 -0.49219 -0.0424 -0.67969 -0.0285 -0.1875 -0.0758 -0.33984 -0.14102 -0.45703 -0.0644 -0.11719 -0.1492 -0.20312 -0.25275 -0.25781 -0.10437 -0.0547 -0.23071 -0.082 -0.37991 -0.082l-0.27801 0z" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_ld.xml b/core/res/res/drawable/ic_signal_wifi_badged_ld.xml deleted file mode 100644 index e2971aa1cba0..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_ld.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-371.33557 310.98651l0 -5.68701 1.39068 0c0.27848 0 0.53336 0.0532 0.76465 0.16016 0.2313 0.10693 0.42954 0.2622 0.59568 0.46679 0.16519 0.20459 0.29357 0.45557 0.38421 0.75391 0.0906 0.29834 0.13593 0.63867 0.13593 1.02148l0 0.88672c0 0.38281 -0.0453 0.72363 -0.13593 1.021 -0.0906 0.29785 -0.21902 0.5498 -0.38421 0.7539 -0.16614 0.20411 -0.36628 0.35938 -0.59946 0.46485 -0.23316 0.10547 -0.49182 0.1582 -0.77786 0.1582l-1.37369 0zm1.06879 -4.76904l0 3.85107 0.26333 0c0.15491 0 0.28452 -0.0283 0.38971 -0.084 0.10516 -0.0557 0.19077 -0.14356 0.25681 -0.26367 0.066 -0.12012 0.11331 -0.27198 0.14184 -0.4585 0.0285 -0.18652 0.0424 -0.41113 0.0424 -0.67383l0 -0.89453c0 -0.26562 -0.0138 -0.49219 -0.0424 -0.67969 -0.0285 -0.1875 -0.0758 -0.33984 -0.14102 -0.45703 -0.0644 -0.11719 -0.1492 -0.20312 -0.25275 -0.25781 -0.10437 -0.0547 -0.23071 -0.082 -0.37991 -0.082l-0.27801 0z" - android:fillColor="#FFFFFF" /> - <path - android:pathData="M-373.13333 310.13333l1.33334 0 0 0.86667 -2.46667 0 0 -5.66666 1.13333 0 0 4.79999z" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/drawable/ic_signal_wifi_badged_sd.xml b/core/res/res/drawable/ic_signal_wifi_badged_sd.xml deleted file mode 100644 index b073be36e840..000000000000 --- a/core/res/res/drawable/ic_signal_wifi_badged_sd.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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:viewportWidth="18" - android:viewportHeight="18" - android:width="26dp" - android:height="24dp"> - <group - android:translateX="386" - android:translateY="-298"> - <path - android:pathData="M-371.33557 310.98651l0 -5.68701 1.39068 0c0.27848 0 0.53336 0.0532 0.76465 0.16016 0.2313 0.10693 0.42954 0.2622 0.59568 0.46679 0.16519 0.20459 0.29357 0.45557 0.38421 0.75391 0.0906 0.29834 0.13593 0.63867 0.13593 1.02148l0 0.88672c0 0.38281 -0.0453 0.72363 -0.13593 1.021 -0.0906 0.29785 -0.21902 0.5498 -0.38421 0.7539 -0.16614 0.20411 -0.36628 0.35938 -0.59946 0.46485 -0.23316 0.10547 -0.49182 0.1582 -0.77786 0.1582l-1.37369 0zm1.06879 -4.76904l0 3.85107 0.26333 0c0.15491 0 0.28452 -0.0283 0.38971 -0.084 0.10516 -0.0557 0.19077 -0.14356 0.25681 -0.26367 0.066 -0.12012 0.11331 -0.27198 0.14184 -0.4585 0.0285 -0.18652 0.0424 -0.41113 0.0424 -0.67383l0 -0.89453c0 -0.26562 -0.0138 -0.49219 -0.0424 -0.67969 -0.0285 -0.1875 -0.0758 -0.33984 -0.14102 -0.45703 -0.0644 -0.11719 -0.1492 -0.20312 -0.25275 -0.25781 -0.10437 -0.0547 -0.23071 -0.082 -0.37991 -0.082l-0.27801 0z" - android:fillColor="#FFFFFF" /> - <path - android:pathData="M-372.87598 309.47461c0 -0.10645 -0.01 -0.20117 -0.0303 -0.28223 -0.0205 -0.0811 -0.0576 -0.15527 -0.11035 -0.22265 -0.0537 -0.0674 -0.12598 -0.12891 -0.21777 -0.18457 -0.0908 -0.0566 -0.20704 -0.11231 -0.34668 -0.16797 -0.24903 -0.0889 -0.47657 -0.18457 -0.68165 -0.28614 -0.20605 -0.10156 -0.38281 -0.2207 -0.53027 -0.35839 -0.14746 -0.13721 -0.26172 -0.29639 -0.34277 -0.47803 -0.0811 -0.18164 -0.12207 -0.39697 -0.12207 -0.646 0 -0.23144 0.042 -0.4414 0.12793 -0.63086 0.085 -0.18945 0.20312 -0.35205 0.35644 -0.48779 0.15235 -0.13623 0.33496 -0.2417 0.54883 -0.31641 0.21289 -0.0752 0.44824 -0.1123 0.70508 -0.1123 0.2666 0 0.50683 0.0425 0.71973 0.12744 0.21386 0.0854 0.39648 0.2041 0.54687 0.35645 0.15137 0.15234 0.26758 0.333 0.34766 0.54101 0.0791 0.2085 0.11914 0.43604 0.11914 0.68262l-1.07422 0c0 -0.11963 -0.0127 -0.22998 -0.0381 -0.33154 -0.0254 -0.10205 -0.0654 -0.18897 -0.12011 -0.26123 -0.0547 -0.0723 -0.125 -0.12891 -0.20997 -0.16993 -0.085 -0.0405 -0.1875 -0.0605 -0.30664 -0.0605 -0.11132 0 -0.208 0.0171 -0.29004 0.0513 -0.0811 0.0342 -0.14843 0.0815 -0.20117 0.14111 -0.0537 0.0596 -0.0928 0.13037 -0.11816 0.21143 -0.0254 0.0815 -0.0381 0.16894 -0.0381 0.26318 0 0.0937 0.0166 0.17725 0.0508 0.24951 0.0342 0.0723 0.0869 0.14014 0.15625 0.20361 0.0703 0.064 0.16016 0.125 0.26856 0.18311 0.10937 0.0586 0.23926 0.11963 0.38965 0.1831 0.24316 0.084 0.46093 0.17823 0.65136 0.2837 0.19043 0.10498 0.35059 0.22998 0.48047 0.37158 0.12891 0.14258 0.22754 0.30762 0.29493 0.49316 0.0674 0.1875 0.10156 0.40235 0.10156 0.64649 0 0.24121 -0.04 0.458 -0.12012 0.64843 -0.0801 0.19043 -0.19434 0.35059 -0.3418 0.48145 -0.14746 0.13086 -0.32617 0.23144 -0.53711 0.30176 -0.21093 0.0693 -0.44726 0.10449 -0.70898 0.10449 -0.23633 0 -0.46777 -0.0361 -0.69531 -0.1084 -0.22754 -0.0723 -0.43067 -0.18359 -0.61035 -0.33203 -0.17872 -0.14844 -0.32325 -0.33691 -0.43262 -0.56543 -0.10938 -0.22852 -0.16309 -0.49805 -0.16309 -0.80859l1.07813 0c0 0.17089 0.0166 0.31445 0.0498 0.43261 0.0332 0.11817 0.084 0.21485 0.15235 0.29004 0.0684 0.0752 0.15429 0.12891 0.25683 0.16211 0.10352 0.0332 0.22461 0.0488 0.36426 0.0488 0.11719 0 0.21582 -0.0156 0.2959 -0.0488 0.0801 -0.0332 0.14355 -0.0781 0.19238 -0.13574 0.0478 -0.0566 0.082 -0.125 0.10254 -0.2041 0.0205 -0.0781 0.0303 -0.16504 0.0303 -0.25879z" - android:fillColor="#FFFFFF" /> - </group> -</vector> diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml index 373354a6cad3..0697b0e3ea9e 100644 --- a/core/res/res/layout/resolver_list.xml +++ b/core/res/res/layout/resolver_list.xml @@ -129,6 +129,18 @@ android:enabled="false" android:text="@string/activity_resolver_use_always" android:onClick="onButtonClick" /> + + <Button + android:id="@+id/button_app_settings" + android:layout_width="wrap_content" + android:layout_gravity="end" + android:maxLines="2" + android:minHeight="@dimen/alert_dialog_button_bar_height" + style="?attr/buttonBarPositiveButtonStyle" + android:layout_height="wrap_content" + android:enabled="false" + android:text="@string/activity_resolver_app_settings" + android:onClick="onButtonClick" /> </LinearLayout> </com.android.internal.widget.ResolverDrawerLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 266e846d8641..3f23da6a499e 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Laat die program toe om toegang tot die foonfunksies van die toestel te verkry. Hierdie toestemming laat die program toe om te bepaal wat die foonnommer en toestel-IDs is, of die oproep aan die gang is, en die afgeleë nommer wat deur \'n oproep verbind word."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"roeteer oproepe deur die stelsel"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Laat die program toe om sy oproepe deur die stelsel te stuur om die oproepervaring te verbeter."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"sien en beheer oproepe deur die stelsel."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Laat die program toe om deurlopende oproepe op die toestel te sien en te beheer. Dit sluit inligting in soos oproepnommers vir oproepe en die toedrag van die oproepe."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"gaan voort met \'n oproep uit \'n ander program"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Laat die program toe om \'n oproep voort te sit wat in \'n ander program begin is."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lees foonnommers"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Laat die program toe om met kortveldkommunikasie- (NFC) merkers, kaarte en lesers te kommunikeer."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktiveer jou skermslot"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Laat die program toe om die sleutelslot en enige verwante wagwoordsekuriteit te deaktiveer. Byvoorbeeld, die foon deaktiveer die sleutelslot wanneer ’n oproep inkom, en atkiveer dit dan weer wanneer die oproep eindig."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"kry en versoek skermslotkompleksiteit"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Laat die program toe om die skermslot-kompleksiteitvlak (hoog, medium, laag of geen) te leer, wat die moontlike omvang van die lengte en soort skermslot aandui. Hierdie program kan ook aan gebruikers voorstel dat hulle die skermslot na \'n sekere vlak toe opdateer, maar gebruikers kan dit vrylik ignoreer en weggaan. Let daarop dat die skermslot nie in skoonteks geberg word nie sodat die program nie die presiese wagwoord ken nie."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"gebruik biometriese hardeware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Laat die program toe om biometriese hardeware vir stawing te gebruik"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"bestuur vingerafdrukhardeware"</string> @@ -1086,7 +1090,7 @@ <string name="email" msgid="4560673117055050403">"E-pos"</string> <string name="email_desc" msgid="3638665569546416795">"Stuur e-pos aan gekose adres"</string> <string name="dial" msgid="1253998302767701559">"Bel"</string> - <string name="dial_desc" msgid="6573723404985517250">"Bel gekose foonnommer"</string> + <string name="dial_desc" msgid="6573723404985517250">"Bel dié foonnommer"</string> <string name="map" msgid="5441053548030107189">"Kaart"</string> <string name="map_desc" msgid="1836995341943772348">"Soek geselekteerde adres"</string> <string name="browse" msgid="1245903488306147205">"Maak oop"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet dateer tans oop …"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Toestel dateer tans op …"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Foon begin tans …"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android begin tans …"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet begin tans …"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Toestel begin tans …"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimeer tans berging."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerke"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Gekoppel aan Wi‑Fi-netwerk wat voorgestel is deur <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Wil jy <xliff:g id="NAME">%s</xliff:g> toelaat om netwerke vir jou voor te stel?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi sal outomaties aanskakel"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wanneer jy naby \'n gestoorde hoëgehaltenetwerk is"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Moenie weer aanskakel nie"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index f3b4df73dd7f..ca1aabd553eb 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"መተግበሪያው የመሳሪያውን የስልክ ባህሪያት ላይ እንዲደርስ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያው የስልክ ቁጥሩን እና የመሳሪያውን መታወቂያዎች፣ ጥሪ የነቃ እንደሆነ፣ እና በጥሪ የተገናኘውን የሩቅ ቁጥር እንዲወስን ይፈቅድለታል።"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ጥሪዎችን በስርዓቱ በኩል አዙር"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"መተግበሪያው የጥሪ ተሞክሮን እንዲያሻሽል ጥሪዎቹን በስርዓቱ በኩል እንዲያዞር ያስችለዋል።"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"በሥርዓቱ በኩል ጥሪዎችን ይመልከቱ እና ይቆጣጠሩ።"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"መተግበሪያው በመሣሪያው ላይ በመካሄድ ላይ ያሉ ጥሪዎችን እንዲመለከት እና እንዲቆጣጠር ይፈቅድለታል። ይህ ለጥሪዎች እንደ የጥሪ ቁጥሮች እና የጥሪዎች ሁኔታ የመሰለ መረጃን ያካትታል።"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"በሌላ መተግበሪያ የተጀመረ ጥሪን መቀጠል"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"መተግበሪያው በሌላ መተግበሪያ ውስጥ የተጀመረ ጥሪ እንዲቀጥል ያስችለዋል።"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ስልክ ቁጥሮች ያንብቡ"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"የማያ ገጽ መቆለፊያ ውስብስብነት ያግኙ እና ይጠይቁ"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"መተግበሪያው የማያ ገጽ መቆለፊያው ውስብስብነት ደረጃ (ከፍተኛ፣ መካከለኛ፣ ዝቅተኛ ወይም ምንም) እንዲያውቅ ያስችለዋል፣ ይህም ሊሆኑ የሚችለው የማያ ገጽ መቆለፊያው ርዝመት እና አይነት ክልል ያመለክታል። መተግበሪያው እንዲሁም ለተጠቃሚዎች የማያ ገጽ መቆለፊያውን ወደተወሰነ ደረጃ እንዲያዘምኑት ሊጠቁማቸው ይችላል። የማያ ገጽ መቆለፊያው በስነጣ አልባ ጽሑፍ እንደማይከማች ልብ ይበሉ፣ በዚህም መተግበሪያው ትክክለኛውን የይለፍ ቃል አያውቅም።"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ባዮሜትራዊ ሃርድዌርን መጠቀም"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"መተግበሪያው የባዮሜትራዊ ሃርድዌር ለማረጋገጥ ስራ እንዲጠቀም ያስችለዋል"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"የጣት አሻራ ሃርድዌርን አስተዳድር"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ጡባዊ በመዘመን ላይ ነው…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"መሣሪያ በመዘመን ላይ ነው…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ስልክ በመጀመር ላይ ነው…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android በመጀመር ላይ ነው…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ጡባዊ በመጀመር ላይ ነው…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"መሣሪያ በመጀመር ላይ ነው…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ማከማቻን በማመቻቸት ላይ።"</string> @@ -1239,6 +1244,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="1524719325616630906">"በ<xliff:g id="NAME">%s</xliff:g> ከተጠቆመው Wi-Fi ጋር ተገናኝቷል"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> አውታረ መረቦችን ለእርስዎ እንዲጠቁሙ ይፈልጋሉ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ከፍተኛ ጥራት ያለው የተቀመጠ አውታረ መረብ አቅራቢያ ሲሆኑ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"መልሰህ አታብራ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 078901384868..455756357bce 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -313,7 +313,7 @@ <string name="permgrouprequest_activityRecognition" msgid="8121253142311250055">"هل تريد السماح للتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالتعرّف على نشاطك البدني؟"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"الكاميرا"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"التقاط صور وتسجيل فيديو"</string> - <string name="permgrouprequest_camera" msgid="1299833592069671756">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالتقاط الصور وتسجيل الفيديو؟"</string> + <string name="permgrouprequest_camera" msgid="1299833592069671756">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالتقاط صور وتسجيل فيديو؟"</string> <string name="permgrouplab_calllog" msgid="8798646184930388160">"سجلّ المكالمات"</string> <string name="permgroupdesc_calllog" msgid="3006237336748283775">"قراءة سجلّ المكالمات الهاتفية والكتابة إليه"</string> <string name="permgrouprequest_calllog" msgid="8487355309583773267">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالدخول إلى سجلات مكالماتك الهاتفية؟"</string> @@ -459,6 +459,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"للسماح للتطبيق بالدخول إلى ميزات الهاتف في الجهاز. ويتيح هذا الإذن للتطبيق تحديد رقم الهاتف ومعرّفات الجهاز، وما إذا كانت هناك مكالمة نشطة والرقم البعيد الذي تم الاتصال به في المكالمة."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"توجيه المكالمات من خلال النظام"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"يسمح للتطبيق بتوجيه المكالمات من خلال النظام لتحسين تجربة الاتصال."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"رؤية المكالمات والتحكّم فيها من خلال النظام"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"يستطيع التطبيق رؤية المكالمات الجارية على الجهاز والتحكّم فيها. ويشمل ذلك معلومات مثل الأرقام وحالة المكالمات."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"مواصلة مكالمة من تطبيق آخر"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"السماح للتطبيق بمواصلة مكالمة بدأت في تطبيق آخر."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"قراءة أرقام الهواتف"</string> @@ -519,6 +521,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"طلب قفل شاشة صعب والحصول عليه"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"للسماح للتطبيق بمعرفة مستوى صعوبة قفل الشاشة (عالي أو متوسط أو منخفض الصعوبة أو بدون)، والذي يحدّد النطاق المحتمل لطول ونوع قفل الشاشة. ويمكن أن يقترح التطبيق للمستخدمين أيضًا تعديل قفل الشاشة إلى مستوى معيّن، ولهم مطلق الحرية في تجاهل هذا الاقتراح ورفضه. وتجدر الإشارة إلى أنه لا يتم حفظ قفل الشاشة في نص عادي، لذا لا يعرف التطبيق كلمة المرور تحديدًا."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"استخدام الأجهزة البيومترية"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"للسماح للتطبيق باستخدام الأجهزة البيومترية للمصادقة"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"لإدارة أجهزة بصمة الإصبع"</string> @@ -1163,15 +1167,15 @@ <string name="deleteText" msgid="6979668428458199034">"حذف"</string> <string name="inputMethod" msgid="1653630062304567879">"طريقة الإرسال"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string> - <string name="email" msgid="4560673117055050403">"بريد إلكتروني"</string> + <string name="email" msgid="4560673117055050403">"إرسال بريد إلكتروني"</string> <string name="email_desc" msgid="3638665569546416795">"مراسلة العنوان المختار عبر البريد الإلكتروني"</string> <string name="dial" msgid="1253998302767701559">"اتصال"</string> <string name="dial_desc" msgid="6573723404985517250">"الاتصال برقم الهاتف المختار"</string> - <string name="map" msgid="5441053548030107189">"خريطة"</string> + <string name="map" msgid="5441053548030107189">"فتح تطبيق خرائط"</string> <string name="map_desc" msgid="1836995341943772348">"تحديد موقع العنوان المختار"</string> <string name="browse" msgid="1245903488306147205">"فتح"</string> <string name="browse_desc" msgid="8220976549618935044">"فتح عنوان URL المختار"</string> - <string name="sms" msgid="4560537514610063430">"رسالة"</string> + <string name="sms" msgid="4560537514610063430">"إرسال رسائل قصيرة"</string> <string name="sms_desc" msgid="7526588350969638809">"مراسلة رقم الهاتف المختار"</string> <string name="add_contact" msgid="7867066569670597203">"إضافة"</string> <string name="add_contact_desc" msgid="4830217847004590345">"إضافة إلى جهات الاتصال"</string> @@ -1261,6 +1265,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"جارٍ تحديث الجهاز اللوحي…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"جارٍ تحديث الجهاز…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"جارٍ بدء تشغيل الهاتف…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"جارٍ تشغيل Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"جارٍ بدء تشغيل الجهاز اللوحي…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"جارٍ بدء تشغيل الجهاز…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"جارٍ تحسين مساحة التخزين."</string> @@ -1327,6 +1332,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="1524719325616630906">"تم الاتصال بشبكة Wi‑Fi التي اقترحها <xliff:g id="NAME">%s</xliff:g>."</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"هل تريد السماح لـ <xliff:g id="NAME">%s</xliff:g> باقتراح شبكات لك؟"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"عندما تكون بالقرب من شبكة محفوظة عالية الجودة"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"عدم إعادة التشغيل"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index f716579d8194..a4f950a9f6b2 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -35,10 +35,10 @@ <string name="mmiError" msgid="5154499457739052907">"সংযোগৰ সমস্যা বা MMI ক\'ড মান্য নহয়।"</string> <string name="mmiFdnError" msgid="5224398216385316471">"কেৱল ফিক্সড ডায়েলিং নম্বৰৰ বাবে কার্য সীমাবদ্ধ কৰা হৈছে।"</string> <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"আপুনি ৰ\'মিঙত থকাৰ সময়ত কল ফৰৱাৰ্ডিঙৰ ছেটিংসমূহ সলনি কৰিব নোৱাৰি।"</string> - <string name="serviceEnabled" msgid="8147278346414714315">"সেৱা সক্ষম কৰা হ\'ল।"</string> - <string name="serviceEnabledFor" msgid="6856228140453471041">"সেৱা সক্ষম কৰা হ\'ল:"</string> - <string name="serviceDisabled" msgid="1937553226592516411">"সেৱা অক্ষম কৰা হ\'ল।"</string> - <string name="serviceRegistered" msgid="6275019082598102493">"পঞ্জীকৰণ সফল হ\'ল।"</string> + <string name="serviceEnabled" msgid="8147278346414714315">"সেৱা সক্ষম কৰা হ’ল।"</string> + <string name="serviceEnabledFor" msgid="6856228140453471041">"সেৱা সক্ষম কৰা হ’ল:"</string> + <string name="serviceDisabled" msgid="1937553226592516411">"সেৱা অক্ষম কৰা হ’ল।"</string> + <string name="serviceRegistered" msgid="6275019082598102493">"পঞ্জীকৰণ সফল হ’ল।"</string> <string name="serviceErased" msgid="1288584695297200972">"সফলভাৱে মচা হ\'ল৷"</string> <string name="passwordIncorrect" msgid="7612208839450128715">"ভুল পাছৱৰ্ড৷"</string> <string name="mmiComplete" msgid="8232527495411698359">"MMI সম্পূৰ্ণ হ’ল।"</string> @@ -66,7 +66,7 @@ <string name="PwdMmi" msgid="7043715687905254199">"পাছৱর্ড সলনি কৰা"</string> <string name="PinMmi" msgid="3113117780361190304">"পিন সলনি কৰা"</string> <string name="CnipMmi" msgid="3110534680557857162">"বর্তমান কল কৰা নম্বৰ"</string> - <string name="CnirMmi" msgid="3062102121430548731">"বর্তমান কল কৰা নম্বৰ সীমিত কৰা হ\'ল"</string> + <string name="CnirMmi" msgid="3062102121430548731">"বর্তমান কল কৰা নম্বৰ সীমিত কৰা হ’ল"</string> <string name="ThreeWCMmi" msgid="9051047170321190368">"ত্ৰিপক্ষীয় কলিং"</string> <string name="RuacMmi" msgid="7827887459138308886">"আমনিদায়ক কল প্ৰত্যাখ্যান"</string> <string name="CndMmi" msgid="3116446237081575808">"কল কৰা নম্বৰত ডেলিভাৰী"</string> @@ -77,20 +77,20 @@ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"কলাৰ আইডি সীমিত নকৰিবলৈ পূর্বনির্ধাৰণ কৰা হৈছে। পৰৱৰ্তী কল: সীমিত কৰা হোৱা নাই"</string> <string name="serviceNotProvisioned" msgid="8614830180508686666">"সুবিধা যোগান ধৰা হোৱা নাই।"</string> <string name="CLIRPermanent" msgid="3377371145926835671">"আপুনি কলাৰ আইডি ছেটিং সলনি কৰিব নোৱাৰে।"</string> - <string name="RestrictedOnDataTitle" msgid="5221736429761078014">"কোনো ম\'বাইল ডেটা সেৱা নাই"</string> + <string name="RestrictedOnDataTitle" msgid="5221736429761078014">"কোনো ম’বাইল ডেটা সেৱা নাই"</string> <string name="RestrictedOnEmergencyTitle" msgid="6855466023161191166">"জৰুৰীকালীন কল কৰাৰ সুবিধা উপলব্ধ নহয়"</string> <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"কোনো ভইচ সেৱা নাই"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"ধ্বনি সেৱা বা জৰুৰীকালীন কলৰ সেৱা উপলব্ধ নহয়"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"আপোনাৰ বাহকে সাময়িকভাৱে অফ কৰি থৈছে"</string> <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"আপোনাৰ বাহকে <xliff:g id="SIMNUMBER">%d</xliff:g> ছিমৰ বাবে সাময়িকভাৱে অফ কৰিছে"</string> - <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"ম\'বাইল নেটৱৰ্কৰ লগত সংযোগ কৰিব পৰা নাই"</string> + <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"ম’বাইল নেটৱৰ্কৰ লগত সংযোগ কৰিব পৰা নাই"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"পচন্দৰ নেটৱৰ্ক সলনি কৰি চেষ্টা কৰি চাওক। সলনি কৰিবলৈ টিপক।"</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"জৰুৰীকালীন কল কৰাৰ সুবিধা উপলব্ধ নহয়"</string> <string name="EmergencyCallWarningSummary" msgid="1899692069750260619">"ৱাই-ফাইৰ জৰিয়তে জৰুৰীকালীন কল কৰিব নোৱাৰি"</string> <string name="notification_channel_network_alert" msgid="4427736684338074967">"সতৰ্কবাণীসমূহ"</string> <string name="notification_channel_call_forward" msgid="2419697808481833249">"কল ফৰৱাৰ্ডিং"</string> <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"জৰুৰীকালীন ক\'লবেক ম\'ড"</string> - <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"ম\'বাইল ডেটাৰ স্থিতি"</string> + <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"ম’বাইল ডেটাৰ স্থিতি"</string> <string name="notification_channel_sms" msgid="3441746047346135073">"এছএমএছ বার্তাবোৰ"</string> <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ভইচমেইলৰ বাৰ্তাসমূহ"</string> <string name="notification_channel_wfc" msgid="2130802501654254801">"ৱাই-ফাই কলিং"</string> @@ -149,7 +149,7 @@ <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ছেকেণ্ডৰ পাছত"</string> <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফৰৱাৰ্ড কৰা নহ\'ল"</string> <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফৰৱাৰ্ড কৰা নহ\'ল"</string> - <string name="fcComplete" msgid="3118848230966886575">"সুবিধাৰ ক\'ড সম্পূর্ণ হ\'ল।"</string> + <string name="fcComplete" msgid="3118848230966886575">"সুবিধাৰ ক\'ড সম্পূর্ণ হ’ল।"</string> <string name="fcError" msgid="3327560126588500777">"সংযোগত সমস্যা হৈছে বা সুবিধাৰ ক\'ড অমান্য।"</string> <string name="httpErrorOk" msgid="1191919378083472204">"ঠিক আছে"</string> <string name="httpError" msgid="7956392511146698522">"ইণ্টাৰনেট সম্পর্কীয় আসোঁৱাহ হ\'ল৷"</string> @@ -176,13 +176,13 @@ <string name="low_memory" product="tv" msgid="516619861191025923">"টিভিৰ সঞ্চয়াগাৰ ভৰি পৰিছে। খালী ঠাই উলিয়াবলৈ কিছুমান ফাইল মচক।"</string> <string name="low_memory" product="default" msgid="3475999286680000541">"ফ\'নৰ সঞ্চয়াগাৰত খালী ঠাই নাই। ঠাই খালী কৰিবলৈ কিছুমান ফাইল মচক।"</string> <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569"> - <item quantity="one">প্ৰমাণপত্ৰ প্ৰদানকাৰী কৰ্তৃপক্ষ ইনষ্টল কৰা হ\'ল</item> - <item quantity="other">প্ৰমাণপত্ৰ প্ৰদানকাৰী কৰ্তৃপক্ষ ইনষ্টল কৰা হ\'ল</item> + <item quantity="one">প্ৰমাণপত্ৰ প্ৰদানকাৰী কৰ্তৃপক্ষ ইনষ্টল কৰা হ’ল</item> + <item quantity="other">প্ৰমাণপত্ৰ প্ৰদানকাৰী কৰ্তৃপক্ষ ইনষ্টল কৰা হ’ল</item> </plurals> <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"এটা অজ্ঞাত তৃতীয় পক্ষৰদ্বাৰা"</string> <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলৰ প্ৰশাসকে পৰ্যবেক্ষণ কৰি আছে"</string> <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>ৰ দ্বাৰা"</string> - <string name="work_profile_deleted" msgid="5005572078641980632">"কৰ্মস্থানৰ প্ৰ\'ফাইল মচা হ\'ল"</string> + <string name="work_profile_deleted" msgid="5005572078641980632">"কৰ্মস্থানৰ প্ৰ\'ফাইল মচা হ’ল"</string> <string name="work_profile_deleted_details" msgid="6307630639269092360">"কৰ্মস্থানৰ প্ৰ\'ফাইলৰ প্ৰশাসক এপ্ নাই বা ব্যৱহাৰযোগ্য হৈ থকা নাই। যাৰ ফলত আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল আৰু ইয়াৰ লগত জড়িত অন্য ডেটাসমূহ মচা হৈছে। সহায়ৰ বাবে আপোনাৰ প্ৰশাসকৰ সৈতে সম্পর্ক কৰক।"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল এই ডিভাইচটোত আৰু উপলব্ধ নহয়"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"বহুতবাৰ ভুলকৈ পাছৱৰ্ড দিয়া হৈছে"</string> @@ -203,9 +203,9 @@ <string name="silent_mode_silent" msgid="319298163018473078">"ৰিংগাৰ অফ আছে"</string> <string name="silent_mode_vibrate" msgid="7072043388581551395">"ৰিংগাৰ কম্পন অৱস্থাত আছে"</string> <string name="silent_mode_ring" msgid="8592241816194074353">"ৰিংগাৰ অন আছে"</string> - <string name="reboot_to_update_title" msgid="6212636802536823850">"Android ছিষ্টেমৰ আপডেট"</string> - <string name="reboot_to_update_prepare" msgid="6305853831955310890">"আপডেট সাজু কৰি থকা হৈছে…"</string> - <string name="reboot_to_update_package" msgid="3871302324500927291">"পেকেজ আপডেট কৰা প্ৰক্ৰিয়া চলি আছে…"</string> + <string name="reboot_to_update_title" msgid="6212636802536823850">"Android ছিষ্টেমৰ আপডে’ট"</string> + <string name="reboot_to_update_prepare" msgid="6305853831955310890">"আপডে’ট সাজু কৰি থকা হৈছে…"</string> + <string name="reboot_to_update_package" msgid="3871302324500927291">"পেকেজ আপডে’ট কৰা প্ৰক্ৰিয়া চলি আছে…"</string> <string name="reboot_to_update_reboot" msgid="6428441000951565185">"ৰিষ্টাৰ্ট কৰা হৈছে…"</string> <string name="reboot_to_reset_title" msgid="4142355915340627490">"ফেক্টৰী ডেটা ৰিছেট কৰক"</string> <string name="reboot_to_reset_message" msgid="2432077491101416345">"ৰিষ্টার্ট হৈ আছে…"</string> @@ -314,20 +314,20 @@ <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> - <string name="permgrouplab_visual" msgid="8030190588123857921">"ফট\' আৰু ভিডিঅ’সমূহ"</string> + <string name="permgrouplab_visual" msgid="8030190588123857921">"ফট’ আৰু ভিডিঅ’"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"আপোনাৰ ফট’ আৰু ভিডিঅ’সমূহ এক্সেছ কৰিবলৈ"</string> <string name="permgrouprequest_visual" msgid="6907523945030290376">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ক আপোনাৰ ফট’ আৰু ভিডিঅ’সমূহ এক্সেছ কৰিবলৈ দিবনে?"</string> - <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ৱিণ্ড\' সমল বিচাৰি উলিয়াওক"</string> - <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপুনি যোগাযোগ কৰি থকা ৱিণ্ড\'খনৰ সমল পৰীক্ষা কৰক।"</string> - <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পৰ্শৰ দ্বাৰা অন্বেষণ কৰাৰ সুবিধা অন কৰক"</string> - <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"টেপ কৰা বস্তুসমূহ ডাঙৰকৈ কোৱা হ\'ব আৰু আঙুলিৰ স্পৰ্শেৰে নিৰ্দেশ দি স্ক্ৰীণ অন্বেষণ কৰিব পাৰিব।"</string> - <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"আপুনি লিখা পাঠ নিৰীক্ষণ কৰক"</string> - <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ক্ৰেডিট কাৰ্ডৰ নম্বৰ আৰু পাছৱৰ্ডৰ দৰে ব্যক্তিগত ডেটা অন্তৰ্ভুক্ত হ\'ব পাৰে।"</string> - <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ডিছপ্লেৰ বিবৰ্ধন নিয়ন্ত্ৰণ কৰক"</string> - <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ডিছপ্লেৰ জুমৰ স্তৰ আৰু অৱস্থান নিয়ন্ত্ৰণ কৰক।"</string> + <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ৱিণ্ড’ সমল বিচাৰি উলিওৱাৰ"</string> + <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপুনি চাই থকা ৱিণ্ড’খনৰ সমল পৰীক্ষা কৰাৰ।"</string> + <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পৰ্শৰ দ্বাৰা অন্বেষণ কৰাৰ সুবিধা অন কৰাৰ"</string> + <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"আঙুলিৰে টিপা বস্তুসমূহ ডাঙৰকৈ কৈ শুনোৱা হ’ব আৰু আঙুলিৰ স্পৰ্শেৰে নিৰ্দেশ দি স্ক্ৰীণ অন্বেষণ কৰিব পাৰিব।"</string> + <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"আপুনি লিখা পাঠ নিৰীক্ষণ কৰাৰ"</string> + <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ক্ৰেডিট কাৰ্ডৰ নম্বৰ আৰু পাছৱৰ্ডৰ দৰে ব্যক্তিগত ডেটা ইয়াত অন্তৰ্ভুক্ত।"</string> + <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ডিছপ্লে’ৰ বিবৰ্ধন নিয়ন্ত্ৰণ কৰাৰ"</string> + <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ডিছপ্লে’ৰ জুমৰ স্তৰ আৰু অৱস্থান নিয়ন্ত্ৰণ কৰাৰ।"</string> <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"আঙুলিৰ স্পৰ্শেৰে নিৰ্দেশ কৰা কার্যসমূহ কৰক"</string> <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"টেপ কৰা, ছোৱাইপ কৰা, পিঞ্চ কৰা আৰু আঙুলিৰ স্পৰ্শেৰে নিৰ্দেশ কৰা অন্যান্য কাৰ্যসমূহ কৰিব পাৰে।"</string> - <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ফিংগাৰপ্ৰিণ্ট নিৰ্দেশসমূহ"</string> + <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ফিংগাৰপ্ৰিণ্ট নিৰ্দেশ"</string> <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"ডিভাইচটোৰ ফিংগাৰপ্ৰিণ্ট ছেন্সৰত দিয়া নিৰ্দেশ বুজিব পাৰে।"</string> <string name="permlab_statusBar" msgid="7417192629601890791">"স্থিতি দণ্ড অক্ষম কৰক বা সলনি কৰক"</string> <string name="permdesc_statusBar" msgid="8434669549504290975">"স্থিতি দণ্ড অক্ষম কৰিবলৈ বা ছিষ্টেম আইকন আঁতৰাবলৈ এপটোক অনুমতি দিয়ে।"</string> @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ডিভাইচত থকা ফ\'নৰ সুবিধাসমূহ ব্য়ৱহাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে৷ এই অনুমতিয়ে কোনো কল সক্ৰিয় হৈ থাককেই বা নাথাকক আৰু দূৰবৰ্তী নম্বৰটো কলৰ দ্বাৰা সংযোজিত হওকেই বা নহওক এপটোক ফ\'ন নম্বৰ আৰু ডিভাইচৰ পৰিচয় নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে৷"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ছিষ্টেমৰ জৰিয়তে কল কৰিব পাৰে"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"কল কৰাৰ অভিজ্ঞতাক উন্নত কৰিবলৈ এপটোক ছিষ্টেমৰ জৰিয়তে কলসমূহ কৰিবলৈ দিয়ে।"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ছিষ্টেমৰ জৰিয়তে কলবোৰ চোৱা আৰু নিয়ন্ত্ৰণ কৰা।"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"এপটোক ডিভাইচত চলি থকা কল চাবলৈ আৰু নিয়ন্ত্ৰণ কৰিবলৈ অনুমতি দিয়ে। কলৰ সংখ্যা আৰু কলবোৰৰ স্থিতি ইয়াত অন্তৰ্ভুক্ত হয়।"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"অইন এটা এপত আৰম্ভ হোৱা কল এটা অব্যাহত ৰাখিব পাৰে"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"এপটোক এনে কল কৰিবলৈ দিয়ে যিটোৰ আৰম্ভণি অইন এটা এপত হৈছিল।"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ফ\'ন নম্বৰসমূহ পঢ়ে"</string> @@ -482,7 +484,7 @@ <string name="permlab_changeTetherState" msgid="5952584964373017960">"টেডাৰিং সংযোগ সলনি কৰক"</string> <string name="permdesc_changeTetherState" msgid="1524441344412319780">"টেডাৰ হৈ থকা ইণ্টাৰনেট সংযোগৰ অৱস্থা সলনি কৰিবলৈ এপটোক অনুমতি দিয়ে৷"</string> <string name="permlab_accessWifiState" msgid="5202012949247040011">"ৱাই-ফাইৰ সংযোগবোৰ চাওক"</string> - <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ৱাই-ফাই সক্ষম কৰা হ\'ল নে নাই আৰু সংযোগ হৈ থকা ৱাই-ফাই ডিভাইচসমূহৰ নামবোৰৰ দৰে ৱাই-ফাইৰ ইণ্টাৰনেট সম্পর্কীয় তথ্য চাবলৈ এপক অনুমতি দিয়ে।"</string> + <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ৱাই-ফাই সক্ষম কৰা হ’ল নে নাই আৰু সংযোগ হৈ থকা ৱাই-ফাই ডিভাইচসমূহৰ নামবোৰৰ দৰে ৱাই-ফাইৰ ইণ্টাৰনেট সম্পর্কীয় তথ্য চাবলৈ এপক অনুমতি দিয়ে।"</string> <string name="permlab_changeWifiState" msgid="6550641188749128035">"ৱাই-ফাই সংযোগ কৰক আৰু ইয়াৰ সংযোগ বিচ্ছিন্ন কৰক"</string> <string name="permdesc_changeWifiState" msgid="7137950297386127533">"এপটোক ৱাই-ফাই এক্সেছ পইণ্টলৈ সংযোগ কৰিবলৈ আৰু তাৰ সংযোগ বিচ্ছিন্ন কৰিবলৈ আৰু ৱাই-ফাই নেটৱৰ্কসমূহৰ বাবে ডিভাইচ কনফিগাৰেশ্বনত সাল-সলনি কৰিবলৈ অনুমতি দিয়ে৷"</string> <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ৱাই-ফাই মাল্টিকাষ্ট প্ৰচাৰৰ অনুমতি দিয়ক"</string> @@ -506,7 +508,9 @@ <string name="permlab_nfc" msgid="4423351274757876953">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string> <string name="permdesc_nfc" msgid="7120611819401789907">"এপটোক নিয়েৰ ফিল্ড কমিউনিকেশ্বন (NFC) টেগ, কাৰ্ড আৰু ৰিডাৰসমূহৰ সৈতে যোগাযোগ কৰিবলৈ অনুমতি দিয়ে।"</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"আপোনাৰ স্ক্ৰীণ ল\'ক অক্ষম কৰক"</string> - <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"এপটোক কী ল\'ক আৰু জড়িত হোৱা যিকোনো পাছৱৰ্ডৰ সুৰক্ষা অক্ষম কৰিব দিয়ে৷ উদাহৰণ স্বৰূপে, কোনো অন্তৰ্গামী ফ\'ন কল উঠোৱাৰ সময়ত ফ\'নটোৱে কী-লকটো অক্ষম কৰে, তাৰপিছত কল শেষ হ\'লেই কী লকটো পুনৰ সক্ষম কৰে৷"</string> + <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"এপটোক কী ল\'ক আৰু জড়িত হোৱা যিকোনো পাছৱৰ্ডৰ সুৰক্ষা অক্ষম কৰিব দিয়ে৷ উদাহৰণস্বৰূপে, কোনো অন্তৰ্গামী ফ\'ন কল উঠোৱাৰ সময়ত ফ\'নটোৱে কী-লকটো অক্ষম কৰে, তাৰ পিছত কল শেষ হ\'লেই কী লকটো পুনৰ সক্ষম কৰে৷"</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"স্ক্ৰীণ ল’কৰ জটিলতা লাভ কৰক আৰু অনুৰোধ কৰক"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"স্ক্ৰীণ ল’কৰ জটিলতাৰ স্তৰ (উচ্চ, মধ্যম, নিম্ন বা একেবাৰে নাই), যি স্ক্ৰীণ ল’কৰ সম্ভাব্য দৈৰ্ঘ্য বা স্ক্ৰীণ ল’কৰ প্ৰকাৰ দৰ্শায় সেইবোৰ শিকিবলৈ এপক অনুমতি দিয়ে। লগতে এপটোৱে ব্যৱহাৰকাৰীক স্ক্ৰীণ ল’কটো এটা নিৰ্দিষ্ট স্তৰলৈ আপডে’ট কৰিবলৈ পৰামৰ্শ দিব পাৰে যিটো ব্যৱহাৰকাৰীয়ে উপেক্ষা কৰি পৰৱর্তী পৃষ্ঠালৈ যাব পাৰে। মনত ৰাখিব যে স্ক্ৰীণ ল’কটো সাধাৰণ পাঠ হিচাপে সঞ্চয় কৰা নহয় সেয়ে এপটোৱে সঠিক পাছৱৰ্ডটো জানিব নোৱাৰে।"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰক"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"বিশ্বাসযোগ্য়তা প্ৰমাণীকৰণৰ বাবে এপক বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ পৰিচালনা কৰিব পাৰে"</string> @@ -542,15 +546,15 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="5309333983002526448">"ফিংগাৰপ্ৰিণ্টৰ সত্যাপন কৰা হ’ল"</string> - <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ\'ল"</string> - <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ\'ল, অনুগ্ৰহ কৰি ‘নিশ্চিত কৰক’ বুটামটো টিপক"</string> + <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string> + <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল, অনুগ্ৰহ কৰি ‘নিশ্চিত কৰক’ বুটামটো টিপক"</string> <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ নাই।"</string> <string name="fingerprint_error_no_space" msgid="1055819001126053318">"ফিংগাৰপ্ৰিণ্ট সঞ্চয় কৰিব পৰা নগ\'ল। পূর্বে সঞ্চিত ফিংগাৰপ্ৰিণ্ট এটা আঁতৰাওক।"</string> <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ফিংগাৰপ্ৰিণ্ট গ্ৰহণৰ সময়সীমা উকলি গৈছে। আকৌ চেষ্টা কৰক।"</string> - <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ফিংগাৰপ্ৰিণ্ট কাৰ্য বাতিল কৰা হ\'ল।"</string> + <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ফিংগাৰপ্ৰিণ্ট কাৰ্য বাতিল কৰা হ’ল।"</string> <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"ব্যৱহাৰকাৰীয়ে ফিংগাৰপ্ৰিণ্ট ক্ৰিয়া বাতিল কৰিছে।"</string> <string name="fingerprint_error_lockout" msgid="5536934748136933450">"অত্যধিক ভুল প্ৰয়াস। কিছুসময়ৰ পাছত আকৌ চেষ্টা কৰক।"</string> - <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"অত্যধিক প্ৰয়াস। ফিংগাৰপ্ৰিণ্ট ছেন্সৰ অক্ষম কৰা হ\'ল।"</string> + <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"অত্যধিক প্ৰয়াস। ফিংগাৰপ্ৰিণ্ট ছেন্সৰ অক্ষম কৰা হ’ল।"</string> <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"আকৌ চেষ্টা কৰক।"</string> <string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string> <string name="fingerprint_error_hw_not_present" msgid="5729436878065119329">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই"</string> @@ -593,7 +597,7 @@ <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ছিংকৰ ছেটিংসমূহ পঢ়ক"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"একাউণ্টৰ ছিংক ছেটিংবোৰ পঢ়িবলৈ এপক অনুমতি দিয়ে। যেনে, People এপ কোনো একাউণ্টত ছিংক কৰা হৈছে নে নাই সেয়া নির্ধাৰণ কৰিব পাৰে।"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ছিংকক অন আৰু অফ ট\'গল কৰক"</string> - <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"এপটোক কোনো একাউণ্টৰ ছিংক সম্পৰ্কীয় ছেটিংসমূহ সংশোধন কৰিবলৈ অনুমতি দিয়ে৷ উদাহৰণ স্বৰূপে, এই কাৰ্যক কোনো একাউণ্টৰ জৰিয়তে People এপটোৰ ছিংক সক্ষম কৰিবলৈ ব্যৱহাৰ কৰিব পাৰি৷"</string> + <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"এপটোক কোনো একাউণ্টৰ ছিংক সম্পৰ্কীয় ছেটিংসমূহ সংশোধন কৰিবলৈ অনুমতি দিয়ে৷ উদাহৰণস্বৰূপে, এই কাৰ্যক কোনো একাউণ্টৰ জৰিয়তে People এপটোৰ ছিংক সক্ষম কৰিবলৈ ব্যৱহাৰ কৰিব পাৰি৷"</string> <string name="permlab_readSyncStats" msgid="7396577451360202448">"ছিংকৰ পৰিসংখ্যা পঢ়ক"</string> <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ছিংকৰ কাৰ্যক্ৰমসমূহৰ ইতিহাস আৰু ছিংক কৰা ডেটাৰ পৰিমাণসহ কোনো একাউণ্টৰ ছিংকৰ তথ্য পঢ়িবলৈ এপক অনুমতি দিয়ে।"</string> <string name="permlab_sdcardRead" msgid="1438933556581438863">"আপোনাৰ শ্বেয়াৰ কৰি ৰখা সঞ্চয়াগাৰৰ সমল পঢ়িব পাৰে"</string> @@ -679,7 +683,7 @@ <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"স্ক্ৰীণ লকৰ কিছুমান সুবিধা ব্যৱহাৰ হোৱাত বাধা দিয়ক।"</string> <string-array name="phoneTypes"> <item msgid="8901098336658710359">"ঘৰ"</item> - <item msgid="869923650527136615">"ম\'বাইল"</item> + <item msgid="869923650527136615">"ম’বাইল"</item> <item msgid="7897544654242874543">"কৰ্মস্থান"</item> <item msgid="1103601433382158155">"কর্মস্থানৰ ফেক্সৰ নম্বৰ"</item> <item msgid="1735177144948329370">"ঘৰৰ ফেক্স নম্বৰ"</item> @@ -722,7 +726,7 @@ </string-array> <string name="phoneTypeCustom" msgid="1644738059053355820">"নিজৰ উপযোগিতা অনুযায়ী"</string> <string name="phoneTypeHome" msgid="2570923463033985887">"ঘৰৰ ফ\'ন নম্বৰ"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"ম\'বাইল"</string> + <string name="phoneTypeMobile" msgid="6501463557754751037">"ম’বাইল"</string> <string name="phoneTypeWork" msgid="8863939667059911633">"কৰ্মস্থানৰ ফ\'ন নম্বৰ"</string> <string name="phoneTypeFaxWork" msgid="3517792160008890912">"কর্মস্থানৰ ফেক্সৰ নম্বৰ"</string> <string name="phoneTypeFaxHome" msgid="2067265972322971467">"ঘৰৰ ফেক্স নম্বৰ"</string> @@ -737,7 +741,7 @@ <string name="phoneTypeRadio" msgid="4093738079908667513">"ৰেডিঅ’ ফ\'ন নম্বৰ"</string> <string name="phoneTypeTelex" msgid="3367879952476250512">"টেলেক্স ফ\'ন নম্বৰ"</string> <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"কৰ্মস্থানৰ ম\'বাইল নম্বৰ"</string> + <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"কৰ্মস্থানৰ ম’বাইল নম্বৰ"</string> <string name="phoneTypeWorkPager" msgid="649938731231157056">"কৰ্মস্থানৰ পেজাৰৰ নম্বৰ"</string> <string name="phoneTypeAssistant" msgid="5596772636128562884">"সহায়ক"</string> <string name="phoneTypeMms" msgid="7254492275502768992">"এমএমএছ"</string> @@ -749,7 +753,7 @@ <string name="emailTypeHome" msgid="449227236140433919">"ঘৰ"</string> <string name="emailTypeWork" msgid="3548058059601149973">"কৰ্মস্থান"</string> <string name="emailTypeOther" msgid="2923008695272639549">"অন্যান্য"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"ম\'বাইল"</string> + <string name="emailTypeMobile" msgid="119919005321166205">"ম’বাইল"</string> <string name="postalTypeCustom" msgid="8903206903060479902">"নিজৰ উপযোগিতা অনুযায়ী"</string> <string name="postalTypeHome" msgid="8165756977184483097">"ঘৰৰ ঠিকনা"</string> <string name="postalTypeWork" msgid="5268172772387694495">"কৰ্মস্থানৰ ঠিকনা"</string> @@ -802,7 +806,7 @@ <string name="keyguard_label_text" msgid="861796461028298424">"আনলক কৰিবলৈ মেনু টিপাৰ পিছত ০ টিপক।"</string> <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"জৰুৰীকালীন নম্বৰ"</string> <string name="lockscreen_carrier_default" msgid="6169005837238288522">"কোনো সেৱা নাই"</string> - <string name="lockscreen_screen_locked" msgid="7288443074806832904">"স্ক্ৰীণ লক কৰা হ\'ল।"</string> + <string name="lockscreen_screen_locked" msgid="7288443074806832904">"স্ক্ৰীণ লক কৰা হ’ল।"</string> <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"আনলক কৰিবলৈ বা জৰুৰীকালীন কল কৰিবলৈ মেনু টিপক।"</string> <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"আনলক কৰিবলৈ মেনু টিপক।"</string> <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"আনলক কৰিবলৈ আর্হি আঁকক"</string> @@ -812,7 +816,7 @@ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"আকৌ চেষ্টা কৰক"</string> <string name="lockscreen_password_wrong" msgid="5737815393253165301">"আকৌ চেষ্টা কৰক"</string> <string name="lockscreen_storage_locked" msgid="9167551160010625200">"সকলো সুবিধা আৰু ডেটাৰ বাবে আনলক কৰক"</string> - <string name="faceunlock_multiple_failures" msgid="754137583022792429">"গৰাকীৰ মুখাৱয়বৰ দ্বাৰা আনলক কৰা সর্বধিক সীমা অতিক্ৰম কৰা হ\'ল"</string> + <string name="faceunlock_multiple_failures" msgid="754137583022792429">"গৰাকীৰ মুখাৱয়বৰ দ্বাৰা আনলক কৰা সর্বধিক সীমা অতিক্ৰম কৰা হ’ল"</string> <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"কোনো ছিম কাৰ্ড নাই"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"টে\'বলেটত ছিম কার্ড নাই।"</string> <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"টিভিত ছিম কার্ড নাই।"</string> @@ -849,7 +853,7 @@ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> ছেকেণ্ডৰ পাছত চেষ্টা কৰক।"</string> <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"আর্হি পাহৰিলে নেকি?"</string> <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"একাউণ্ট আনলক"</string> - <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"বহুতবাৰ ভুলকৈ আর্হি অঁকা হ\'ল"</string> + <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"বহুতবাৰ ভুলকৈ আর্হি অঁকা হ’ল"</string> <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"আনলক কৰিবলৈ নিজৰ Google একাউণ্টৰ জৰিয়তে ছাইন ইন কৰক।"</string> <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ব্যৱহাৰকাৰীৰ নাম (ইমেইল)"</string> <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"পাছৱৰ্ড"</string> @@ -860,11 +864,11 @@ <string name="lockscreen_unlock_label" msgid="737440483220667054">"আনলক"</string> <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ধ্বনি অন হৈ আছে"</string> <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ধ্বনি অফ হৈ আছে"</string> - <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"আর্হি অঁকা কার্য আৰম্ভ হ\'ল"</string> - <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"আর্হি মচি পেলোৱা হ\'ল"</string> + <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"আর্হি অঁকা কার্য আৰম্ভ হ’ল"</string> + <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"আর্হি মচি পেলোৱা হ’ল"</string> <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"আৰ্হিত এটা বিন্দু যোগ কৰিছে"</string> - <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"চেল <xliff:g id="CELL_INDEX">%1$s</xliff:g> যোগ কৰা হ\'ল"</string> - <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"আর্হি অঁকা সর্ম্পূণ হ\'ল"</string> + <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"চেল <xliff:g id="CELL_INDEX">%1$s</xliff:g> যোগ কৰা হ’ল"</string> + <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"আর্হি অঁকা সর্ম্পূণ হ’ল"</string> <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"আর্হিৰ ক্ষেত্ৰ।"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ৱিজেট %3$d-ৰ %2$d।"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ৱিজেট যোগ কৰক।"</string> @@ -876,9 +880,9 @@ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"স্থিতি"</string> <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"কেমেৰা"</string> <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"মিডিয়াৰ নিয়ন্ত্ৰণসমূহ"</string> - <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"ৱিজেটৰ পুনঃক্ৰম আৰম্ভ হ\'ল।"</string> - <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"ৱিজেটৰ পুনঃক্ৰম সমাপ্ত হ\'ল।"</string> - <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ৱিজেট <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> মচা হ\'ল।"</string> + <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"ৱিজেটৰ পুনঃক্ৰম আৰম্ভ হ’ল।"</string> + <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"ৱিজেটৰ পুনঃক্ৰম সমাপ্ত হ’ল।"</string> + <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ৱিজেট <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> মচা হ’ল।"</string> <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"আনলক ক্ষেত্ৰ বিস্তাৰ কৰক।"</string> <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"শ্লাইডৰদ্বাৰা আনলক।"</string> <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"আৰ্হিৰদ্বাৰা আনলক।"</string> @@ -934,7 +938,7 @@ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"আপোনাৰ টিভিত সঞ্চয় কৰি ৰখা ব্ৰাউজাৰৰ বুকমার্ক আৰু ব্ৰাউজাৰৰ ইতিহাস সংশোধন কৰিবলৈ এপক অনুমতি দিয়ে। টোকা: এই অনুমতি তৃতীয় পক্ষৰ ব্ৰাউজাৰবোৰ বা ৱেব ব্ৰাউজিংৰ ক্ষমতা থকা অন্য এপ্লিকেশ্বনবোৰৰ দ্বাৰা বলৱৎ নহ\'বও পাৰে।"</string> <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"আপোনাৰ ফ\'নত সঞ্চয় কৰি ৰখা ব্ৰাউজাৰৰ বুকমার্ক আৰু ব্ৰাউজাৰৰ ইতিহাস সংশোধন কৰিবলৈ এপক অনুমতি দিয়ে। টোকা: এই অনুমতি তৃতীয় পক্ষৰ ব্ৰাউজাৰবোৰ বা ৱেব ব্ৰাউজিং কৰিব পৰা অন্য এপ্লিকেশ্বনবোৰৰ দ্বাৰা বলৱৎ নহ\'বও পাৰে।"</string> <string name="permlab_setAlarm" msgid="1379294556362091814">"এলাৰ্ম ছেট কৰক"</string> - <string name="permdesc_setAlarm" msgid="316392039157473848">"এপটোক ইনষ্টল হৈ থকা এলাৰ্ম ক্লক এপত এলাৰ্ম ছেট কৰিবলৈ অনুমতি দিয়ে। কিছুমান এলাৰ্ম ক্লক এপত এই সুবিধাটো প্ৰযোজ্য নহ\'ব পাৰে।"</string> + <string name="permdesc_setAlarm" msgid="316392039157473848">"এপটোক ইনষ্টল হৈ থকা এলাৰ্ম ক্লক এপত এলাৰ্ম ছেট কৰিবলৈ অনুমতি দিয়ে। কিছুমান এলাৰ্ম ক্লক এপত এই সুবিধাটো প্ৰযোজ্য নহ’ব পাৰে।"</string> <string name="permlab_addVoicemail" msgid="5525660026090959044">"ভইচমেইল যোগ কৰক"</string> <string name="permdesc_addVoicemail" msgid="6604508651428252437">"আপোনাৰ ভইচমেইল ইনবক্সত বাৰ্তাবোৰ যোগ কৰিবলৈ এপটোক অনুমতি দিয়ক।"</string> <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ব্ৰাউজাৰৰ জিঅ\'লোকেশ্বনৰ অনুমতিসমূহ সংশোধন কৰক"</string> @@ -944,7 +948,7 @@ <string name="save_password_remember" msgid="6491879678996749466">"মনত ৰাখিব"</string> <string name="save_password_never" msgid="8274330296785855105">"কেতিয়াও মনত নাৰাখিব"</string> <string name="open_permission_deny" msgid="7374036708316629800">"এই পৃষ্ঠাটো খুলিবলৈ আপোনাৰ অনুমতি নাই।"</string> - <string name="text_copied" msgid="4985729524670131385">"ক্লিপব\'র্ডলৈ বাৰ্তা প্ৰতিলিপি কৰা হ\'ল।"</string> + <string name="text_copied" msgid="4985729524670131385">"ক্লিপব\'র্ডলৈ বাৰ্তা প্ৰতিলিপি কৰা হ’ল।"</string> <string name="more_item_label" msgid="4650918923083320495">"অধিক"</string> <string name="prepend_shortcut_label" msgid="2572214461676015642">"মেনু+"</string> <string name="menu_meta_shortcut_label" msgid="4647153495550313570">"মেটা+"</string> @@ -1083,22 +1087,22 @@ <string name="deleteText" msgid="6979668428458199034">"মচক"</string> <string name="inputMethod" msgid="1653630062304567879">"ইনপুট পদ্ধতি"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"পাঠ বিষয়ক কাৰ্য"</string> - <string name="email" msgid="4560673117055050403">"ইমেইল"</string> - <string name="email_desc" msgid="3638665569546416795">"বাছনি কৰা ঠিকনাত ইমেইল কৰক"</string> + <string name="email" msgid="4560673117055050403">"ইমেইল কৰক"</string> + <string name="email_desc" msgid="3638665569546416795">"বাছনি কৰা ঠিকনালৈ ইমেইল পঠিয়াওক"</string> <string name="dial" msgid="1253998302767701559">"কল কৰক"</string> <string name="dial_desc" msgid="6573723404985517250">"বাছনি কৰা ফ\'ন নাম্বাৰত কল কৰক"</string> - <string name="map" msgid="5441053548030107189">"মেপ"</string> + <string name="map" msgid="5441053548030107189">"মেপ খোলক"</string> <string name="map_desc" msgid="1836995341943772348">"বাছনি কৰা ঠিকনাটো বিচাৰি উলিয়াওক"</string> <string name="browse" msgid="1245903488306147205">"খোলক"</string> <string name="browse_desc" msgid="8220976549618935044">"বাছনি কৰা URL খোলক"</string> - <string name="sms" msgid="4560537514610063430">"বাৰ্তা"</string> - <string name="sms_desc" msgid="7526588350969638809">"বাছনি কৰা ফ\'ন নাম্বাৰত বাৰ্তা পঠিয়াওক"</string> + <string name="sms" msgid="4560537514610063430">"বাৰ্তা পঠিয়াওক"</string> + <string name="sms_desc" msgid="7526588350969638809">"বাছনি কৰা ফ’ন নম্বৰলৈ বাৰ্তা পঠিয়াওক"</string> <string name="add_contact" msgid="7867066569670597203">"যোগ দিয়ক"</string> <string name="add_contact_desc" msgid="4830217847004590345">"সর্ম্পকসূচীত যোগ কৰক"</string> <string name="view_calendar" msgid="979609872939597838">"চাওক"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"কেলেণ্ডাৰত বাছনি কৰা সময় চাওক"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"সূচী"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"বাছনি কৰা সময়ৰ বাবে কাৰ্যক্ৰমৰ তালিকা বনাওক"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"সময়সূচী নিৰ্ধাৰণ কৰক"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"বাছনি কৰা তাৰিখটো কাৰ্যক্ৰমৰ সময় হিচাপে নিৰ্ধাৰণ কৰক"</string> <string name="view_flight" msgid="7691640491425680214">"ট্ৰেক কৰক"</string> <string name="view_flight_desc" msgid="3876322502674253506">"বাছনি কৰা বিমানটো ট্ৰেক কৰক"</string> <string name="translate" msgid="9218619809342576858">"অনুবাদ কৰক"</string> @@ -1141,12 +1145,12 @@ <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"প্ৰতিচ্ছবি তোলক"</string> <string name="alwaysUse" msgid="4583018368000610438">"এই কার্যৰ বাবে পূর্বনির্ধাৰিত ধৰণে ব্যৱহাৰ কৰক।"</string> <string name="use_a_different_app" msgid="8134926230585710243">"এটা পৃথক এপ্ ব্যৱহাৰ কৰক"</string> - <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ছিষ্টেমৰ ছেটিংসমূহ > এপসমূহ > ডাউনল\'ড কৰা সমল-লৈ গৈ ডিফ\'ল্ট মচক৷"</string> + <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ছিষ্টেমৰ ছেটিংসমূহ > এপসমূহ > ডাউনল’ড কৰা সমল-লৈ গৈ ডিফ\'ল্ট মচক৷"</string> <string name="chooseActivity" msgid="7486876147751803333">"কোনো কার্য বাছনি কৰক"</string> <string name="chooseUsbActivity" msgid="6894748416073583509">"ইউএছবি ডিভাইচৰ বাবে এটা এপ্ বাছনি কৰক"</string> <string name="noApplications" msgid="2991814273936504689">"কোনো এপে এই কাৰ্য কৰিব নোৱাৰে।"</string> - <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> বন্ধ হ\'ল"</string> - <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> বন্ধ হ\'ল"</string> + <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> বন্ধ হ’ল"</string> + <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> বন্ধ হ’ল"</string> <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> @@ -1169,22 +1173,23 @@ <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক পূৰ্বতে লঞ্চ কৰা হৈছিল৷"</string> <string name="screen_compat_mode_scale" msgid="3202955667675944499">"স্কেল"</string> <string name="screen_compat_mode_show" msgid="4013878876486655892">"সদায় দেখুৱাওক"</string> - <string name="screen_compat_mode_hint" msgid="1064524084543304459">"ছিষ্টেমৰ ছেটিংসমূহ > এপসমূহ > ডাউনল\'ড কৰা সমল-লৈ গৈ ইয়াক আকৌ সক্ষম কৰক।"</string> - <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বর্তমানৰ ডিছপ্লেৰ আকাৰ ছেটিং ব্যৱহাৰ কৰিব নোৱাৰে আৰু ই সঠিকভাৱে নচলিবও পাৰে।"</string> + <string name="screen_compat_mode_hint" msgid="1064524084543304459">"ছিষ্টেমৰ ছেটিংসমূহ > এপসমূহ > ডাউনল’ড কৰা সমল-লৈ গৈ ইয়াক আকৌ সক্ষম কৰক।"</string> + <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বর্তমানৰ ডিছপ্লে’ৰ আকাৰ ছেটিং ব্যৱহাৰ কৰিব নোৱাৰে আৰু ই সঠিকভাৱে নচলিবও পাৰে।"</string> <string name="unsupported_display_size_show" msgid="7969129195360353041">"সদায় দেখুৱাওক"</string> <string name="unsupported_compile_sdk_message" msgid="4253168368781441759">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক এটা খাপ নোখোৱা Android OS সংস্কৰণৰ বাবে তৈয়াৰ কৰা হৈছিল, যাৰ ফলত ই অস্বাভাৱিকধৰণে আচৰণ কৰিব পাৰে। এপটোৰ শেহতীয়া সংস্কৰণ উপলব্ধ হ\'ব পাৰে।"</string> <string name="unsupported_compile_sdk_show" msgid="2681877855260970231">"সদায় দেখুৱাওক"</string> - <string name="unsupported_compile_sdk_check_update" msgid="3312723623323216101">"আপডেট আছে নেকি চাওক"</string> + <string name="unsupported_compile_sdk_check_update" msgid="3312723623323216101">"আপডে’ট আছে নেকি চাওক"</string> <string name="smv_application" msgid="3307209192155442829">"এপটোৱে <xliff:g id="APPLICATION">%1$s</xliff:g> (প্ৰক্ৰিয়াটোৱে <xliff:g id="PROCESS">%2$s</xliff:g>) নিজে বলবৎ কৰা StrictMode নীতি ভংগ কৰিলে।"</string> <string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> প্ৰক্ৰিয়াটোৱে নিজে বলৱৎ কৰা StrictMode নীতি ভংগ কৰিলে।"</string> - <string name="android_upgrading_title" product="default" msgid="7513829952443484438">"ফ\'নটো আপডেট হৈ আছে…"</string> - <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"টেবলেটটো আপডেট হৈ আছে…"</string> - <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ডিভাইচটো আপডেট হৈ আছে…"</string> + <string name="android_upgrading_title" product="default" msgid="7513829952443484438">"ফ\'নটো আপডে’ট হৈ আছে…"</string> + <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"টেবলেটটো আপডে’ট হৈ আছে…"</string> + <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ডিভাইচটো আপডে’ট হৈ আছে…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ফ\'নটো আৰম্ভ হৈছে…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android আৰম্ভ কৰি থকা হৈছে…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"টেবলেটটো আৰম্ভ হৈছে…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ডিভাইচটো আৰম্ভ হৈছে…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"সঞ্চয়াগাৰ অপ্টিমাইজ কৰি থকা হৈছে।"</string> - <string name="android_upgrading_notification_title" product="default" msgid="1511552415039349062">"ছিষ্টেম আপডেট সম্পূৰ্ণ কৰা হৈছে…"</string> + <string name="android_upgrading_notification_title" product="default" msgid="1511552415039349062">"ছিষ্টেম আপডে’ট সম্পূৰ্ণ কৰা হৈছে…"</string> <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g>ক আপগ্ৰেড কৰি থকা হৈছে…"</string> <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>ৰ ভিতৰত <xliff:g id="NUMBER_0">%1$d</xliff:g> এপ্ অপ্টিমাইজ কৰি থকা হৈছে৷"</string> <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>সাজু কৰি থকা হৈছে।"</string> @@ -1198,7 +1203,7 @@ <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> - <string name="dump_heap_notification_detail" msgid="3993078784053054141">"হীপ ডাম্প সংগ্ৰহ কৰা হ\'ল। শ্বেয়াৰ কৰিবলৈ টিপক"</string> + <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> <string name="sendText" msgid="5209874571959469142">"বার্তাৰ বাবে কাৰ্য বাছনি কৰক"</string> @@ -1234,15 +1239,19 @@ <string name="wifi_available_title" msgid="3817100557900599505">"পাছৱৰ্ড অবিহনে সংযোগ কৰিবপৰা ৱাই-ফাই নেটৱর্কৰ সৈতে সংযোগ কৰক"</string> <string name="wifi_available_carrier_network_title" msgid="4527932626916527897">"বাহকৰ ৱাই-ফাই নেটৱৰ্কৰ সৈতে সংযোগ কৰক"</string> <string name="wifi_available_title_connecting" msgid="1139126673968899002">"ৱাই-ফাই নেটৱৰ্কৰ সৈতে সংযোগ কৰি থকা হৈছে"</string> - <string name="wifi_available_title_connected" msgid="7542672851522241548">"ৱাই-ফাই নেটৱৰ্কৰ সৈতে সংযোগ কৰা হ\'ল"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"ৱাই-ফাই নেটৱৰ্কৰ সৈতে সংযোগ কৰা হ’ল"</string> <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ৱাই-ফাই নেটৱৰ্কৰ সৈতে সংযোগ কৰিবপৰা নগ\'ল"</string> <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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g>এ প্ৰস্তাৱ দিয়া ৱাই-ফাই নেটৱৰ্কৰ লগত সংযোগ কৰা হ’ল"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"আপুনি <xliff:g id="NAME">%s</xliff:g>ক আপোনাৰ বাবে নেটৱৰ্কৰ প্ৰস্তাৱ দিয়াৰ অনুমতি দিব বিচাৰেনে?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"যেতিয়া আপুনি ছেভ কৰি থোৱা উচ্চ মানৰ নেটৱৰ্কৰ কাষত থাকে"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"পুনৰাই অন নকৰিব"</string> - <string name="wifi_wakeup_enabled_title" msgid="6534603733173085309">"ৱাই-ফাই স্বয়ংক্ৰিয়ভাৱে অন কৰা হ\'ল"</string> + <string name="wifi_wakeup_enabled_title" msgid="6534603733173085309">"ৱাই-ফাই স্বয়ংক্ৰিয়ভাৱে অন কৰা হ’ল"</string> <string name="wifi_wakeup_enabled_content" msgid="189330154407990583">"আপুনি ছেভ কৰি থোৱা নেটৱৰ্ক এটাৰ কাষত আছে: <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ৱাই-ফাই নেটৱৰ্কত ছাইন ইন কৰক"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"নেটৱৰ্কত ছাইন ইন কৰক"</string> @@ -1253,11 +1262,11 @@ <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">"আপোনাৰ কেৱল ৫গিগাহাৰ্টজৰ প্ৰতি অগ্ৰাধিকাৰ এই ডিভাচইচটোৱে সমৰ্থন নকৰে। ইয়াৰ পৰিৱৰ্তে, ডিভাচইচটোৱে যেতিয়া ৫গিগাহাৰ্টজ বেণ্ড উপলব্ধ হ’ব তেতিয়া সেইয়া ব্যৱহাৰ কৰিব।"</string> - <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>লৈ সলনি কৰা হ\'ল"</string> + <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>লৈ সলনি কৰা হ’ল"</string> <string name="network_switch_metered_detail" msgid="775163331794506615">"যেতিয়া <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ত ইণ্টাৰনেট নাথাকে, তেতিয়া ডিভাইচে <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ক ব্যৱহাৰ কৰে। মাচুল প্ৰযোজ্য হ\'ব পাৰে।"</string> - <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>ৰ পৰা <xliff:g id="NEW_NETWORK">%2$s</xliff:g> লৈ সলনি কৰা হ\'ল"</string> + <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>ৰ পৰা <xliff:g id="NEW_NETWORK">%2$s</xliff:g> লৈ সলনি কৰা হ’ল"</string> <string-array name="network_switch_type_name"> - <item msgid="3979506840912951943">"ম\'বাইল ডেটা"</item> + <item msgid="3979506840912951943">"ম’বাইল ডেটা"</item> <item msgid="75483255295529161">"ৱাই-ফাই"</item> <item msgid="6862614801537202646">"ব্লুটুথ"</item> <item msgid="5447331121797802871">"ইথাৰনেট"</item> @@ -1276,7 +1285,7 @@ <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"ছেটিংসমূহৰ বাবে টিপক"</string> <string name="accept" msgid="1645267259272829559">"স্বীকাৰ কৰক"</string> <string name="decline" msgid="2112225451706137894">"প্ৰত্যাখ্যান কৰক"</string> - <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"আমন্ত্ৰণ পঠোৱা হ\'ল"</string> + <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"আমন্ত্ৰণ পঠোৱা হ’ল"</string> <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"সংযোগ হ\'বলৈ আমন্ত্ৰণ"</string> <string name="wifi_p2p_from_message" msgid="570389174731951769">"প্ৰেৰক:"</string> <string name="wifi_p2p_to_message" msgid="248968974522044099">"প্ৰতি:"</string> @@ -1291,30 +1300,30 @@ <string name="sms_control_yes" msgid="3663725993855816807">"অনুমতি দিয়ক"</string> <string name="sms_control_no" msgid="625438561395534982">"অস্বীকাৰ কৰক"</string> <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>এ <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> লৈ কিবা বার্তা প্ৰেৰণ কৰিব বিচাৰিছে।"</string> - <string name="sms_short_code_details" msgid="5873295990846059400">"ইয়াৰ বাবে "<b>" মাছুল ভৰিবলগীয়া হ\'ব পাৰে"</b>"।"</string> - <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ইয়াৰ বাবে মাছুল ভৰিবলগীয়া হ\'ব পাৰে।"</b></string> + <string name="sms_short_code_details" msgid="5873295990846059400">"ইয়াৰ বাবে "<b>" মাচুল ভৰিবলগীয়া হ’ব পাৰে"</b>"।"</string> + <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ইয়াৰ বাবে মাচুল ভৰিবলগীয়া হ’ব পাৰে।"</b></string> <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"পঠিয়াওক"</string> <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"বাতিল কৰক"</string> <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"মোৰ পচন্দ মনত ৰাখিব"</string> <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"আপুনি ইয়াক পিছত ছেটিং > এপ্-ত সলনি কৰিব পাৰে"</string> <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"যিকোনো সময়ত অনুমতি দিয়ক"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"কেতিয়াও অনুমতি নিদিব"</string> - <string name="sim_removed_title" msgid="6227712319223226185">"ছিম কাৰ্ড আঁতৰোৱা হ\'ল"</string> + <string name="sim_removed_title" msgid="6227712319223226185">"ছিম কাৰ্ড আঁতৰোৱা হ’ল"</string> <string name="sim_removed_message" msgid="2333164559970958645">"এখন মান্য ছিম কার্ড ব্যৱহাৰ কৰি ৰিষ্টার্ট নকৰা পর্যন্ত ম\'বাইলৰ নেটৱর্ক উপলব্ধ নহয়।"</string> - <string name="sim_done_button" msgid="827949989369963775">"সম্পন্ন হ\'ল"</string> - <string name="sim_added_title" msgid="3719670512889674693">"ছিম কাৰ্ড যোগ কৰা হ\'ল"</string> + <string name="sim_done_button" msgid="827949989369963775">"সম্পন্ন হ’ল"</string> + <string name="sim_added_title" msgid="3719670512889674693">"ছিম কাৰ্ড যোগ কৰা হ’ল"</string> <string name="sim_added_message" msgid="6599945301141050216">"ম\'বাইলৰ নেটৱর্ক ব্যৱহাৰ কৰিবলৈ আপোনাৰ ডিভাইচটো ৰিষ্টার্ট কৰক।"</string> <string name="sim_restart_button" msgid="4722407842815232347">"ৰিষ্টাৰ্ট কৰক"</string> - <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"ম\'বাইল সেৱা সক্ৰিয় কৰক"</string> - <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"আপোনাৰ নতুন ছিমখন সক্ৰিয় কৰিবলৈ বাহকৰ এপটো ডাউনল\'ড কৰক"</string> - <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"আপোনাৰ নতুন ছিমখন সক্ৰিয় কৰিবলৈ <xliff:g id="APP_NAME">%1$s</xliff:g> এপটো ডাউনল\'ড কৰক"</string> - <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"এপ্ ডাউনল\'ড কৰক"</string> + <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"ম’বাইল সেৱা সক্ৰিয় কৰক"</string> + <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"আপোনাৰ নতুন ছিমখন সক্ৰিয় কৰিবলৈ বাহকৰ এপটো ডাউনল’ড কৰক"</string> + <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"আপোনাৰ নতুন ছিমখন সক্ৰিয় কৰিবলৈ <xliff:g id="APP_NAME">%1$s</xliff:g> এপটো ডাউনল’ড কৰক"</string> + <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"এপ্ ডাউনল’ড কৰক"</string> <string name="carrier_app_notification_title" msgid="8921767385872554621">"নতুন ছিম ভৰোৱা হৈছে"</string> <string name="carrier_app_notification_text" msgid="1132487343346050225">"ছেট আপ কৰিবলৈ টিপক"</string> <string name="time_picker_dialog_title" msgid="8349362623068819295">"সময় ছেট কৰক"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"তাৰিখ ছেট কৰক"</string> <string name="date_time_set" msgid="5777075614321087758">"ছেট কৰক"</string> - <string name="date_time_done" msgid="2507683751759308828">"সম্পন্ন হ\'ল"</string> + <string name="date_time_done" msgid="2507683751759308828">"সম্পন্ন হ’ল"</string> <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"নতুন: "</font></string> <string name="perms_description_app" msgid="5139836143293299417">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ প্ৰদান কৰা"</string> <string name="no_permissions" msgid="7283357728219338112">"কোনো অনুমতিৰ প্ৰয়োজন নাই"</string> @@ -1322,16 +1331,16 @@ <string name="dlg_ok" msgid="7376953167039865701">"ঠিক আছে"</string> <string name="usb_charging_notification_title" msgid="1595122345358177163">"ইউএছবিৰ জৰিয়তে এই ডিভাইচটো চ্চাৰ্জ কৰি থকা হৈছে"</string> <string name="usb_supplying_notification_title" msgid="4631045789893086181">"ইউএছবিৰ জৰিয়তে সংযুক্ত ডিভাইচটো চ্চাৰ্জ কৰি থকা হৈছে"</string> - <string name="usb_mtp_notification_title" msgid="4238227258391151029">"ইউএছবি জৰিয়তে ফাইল স্থানান্তৰণ অন কৰা হ\'ল"</string> - <string name="usb_ptp_notification_title" msgid="5425857879922006878">"ইউএছবিৰ জৰিয়তে পিটিপি অন কৰা হ\'ল"</string> - <string name="usb_tether_notification_title" msgid="3716143122035802501">"ইউএছবি টেডাৰিং অন কৰা হ\'ল"</string> - <string name="usb_midi_notification_title" msgid="5356040379749154805">"ইউএছবিৰ জৰিয়তে এমআইডিআই অন কৰা হ\'ল"</string> - <string name="usb_accessory_notification_title" msgid="1785694450621427730">"ইউএছবি সহায়ক সামগ্ৰী সংযোগ কৰা হ\'ল"</string> + <string name="usb_mtp_notification_title" msgid="4238227258391151029">"ইউএছবি জৰিয়তে ফাইল স্থানান্তৰণ অন কৰা হ’ল"</string> + <string name="usb_ptp_notification_title" msgid="5425857879922006878">"ইউএছবিৰ জৰিয়তে পিটিপি অন কৰা হ’ল"</string> + <string name="usb_tether_notification_title" msgid="3716143122035802501">"ইউএছবি টেডাৰিং অন কৰা হ’ল"</string> + <string name="usb_midi_notification_title" msgid="5356040379749154805">"ইউএছবিৰ জৰিয়তে এমআইডিআই অন কৰা হ’ল"</string> + <string name="usb_accessory_notification_title" msgid="1785694450621427730">"ইউএছবি সহায়ক সামগ্ৰী সংযোগ কৰা হ’ল"</string> <string name="usb_notification_message" msgid="3370903770828407960">"অধিক বিকল্পৰ বাবে টিপক।"</string> <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">"ইউএছবি ডিবাগিং সংযোগ কৰা হ\'ল"</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"ইউএছবি ডিবাগিং সংযোগ কৰা হ’ল"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"ইউএছবি ডিবাগিং বন্ধ কৰিবলৈ টিপক"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ইউএছবি ডিবাগিং অক্ষম কৰিবলৈ বাছনি কৰক।"</string> <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"বাগ সম্পর্কীয় অভিযোগ গ্ৰহণ কৰি থকা হৈছে…"</string> @@ -1364,9 +1373,9 @@ <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g>ক ব্যৱহাৰ কৰিব নোৱাৰি"</string> <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"এই ডিভাইচটোৱে <xliff:g id="NAME">%s</xliff:g>ক ব্যৱহাৰ কৰিব নোৱাৰে। ব্যৱহাৰ কৰিব পৰা ফৰ্মেটত ছেট আপ কৰিবলৈ টিপক।"</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"এই ডিভাইচটোৱে <xliff:g id="NAME">%s</xliff:g>ক চলাব নোৱাৰে। চলাব পৰা কোনো ফৰ্মেটত ছেট আপ কৰিবলৈ বাছনি কৰক।"</string> - <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> অপ্ৰত্য়াশিতভাৱে আঁতৰোৱা হ\'ল"</string> + <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> অপ্ৰত্য়াশিতভাৱে আঁতৰোৱা হ’ল"</string> <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"সমল হেৰুওৱাৰ পৰা হাত সাৰিবলৈ আঁতৰোৱাৰ আগতে মিডিয়া বাহিৰ কৰক"</string> - <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> আঁতৰোৱা হ\'ল"</string> + <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> আঁতৰোৱা হ’ল"</string> <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"কিছুমান কাৰ্যক্ষমতাই সঠিকভাৱে কাম নকৰিব পাৰে। নতুন সঞ্চয়াগাৰ ভৰাওক।"</string> <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"<xliff:g id="NAME">%s</xliff:g> বাহিৰ কৰি থকা হৈছে"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"আঁতৰাই নিদিব"</string> @@ -1377,16 +1386,16 @@ <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> <string name="ext_media_move_title" msgid="1022809140035962662">"ডেটা স্থানান্তৰ কৰি থকা হৈছে"</string> - <string name="ext_media_move_success_title" msgid="7863652232242276066">"সমলৰ স্থানান্তৰণ সমাপ্ত হ\'ল"</string> - <string name="ext_media_move_success_message" msgid="8939137931961728009">"<xliff:g id="NAME">%s</xliff:g>লৈ সমল স্থানান্তৰ কৰা হ\'ল"</string> + <string name="ext_media_move_success_title" msgid="7863652232242276066">"সমলৰ স্থানান্তৰণ সমাপ্ত হ’ল"</string> + <string name="ext_media_move_success_message" msgid="8939137931961728009">"<xliff:g id="NAME">%s</xliff:g>লৈ সমল স্থানান্তৰ কৰা হ’ল"</string> <string name="ext_media_move_failure_title" msgid="1604422634177382092">"সমল স্থানান্তৰ কৰিব পৰা নগ\'ল"</string> <string name="ext_media_move_failure_message" msgid="7388950499623016135">"সমল আকৌ স্থানান্তৰ কৰিবলৈ চেষ্টা কৰক"</string> - <string name="ext_media_status_removed" msgid="6576172423185918739">"আঁতৰোৱা হ\'ল"</string> - <string name="ext_media_status_unmounted" msgid="2551560878416417752">"বাহিৰলৈ উলিওৱা হ\'ল"</string> + <string name="ext_media_status_removed" msgid="6576172423185918739">"আঁতৰোৱা হ’ল"</string> + <string name="ext_media_status_unmounted" msgid="2551560878416417752">"বাহিৰলৈ উলিওৱা হ’ল"</string> <string name="ext_media_status_checking" msgid="6193921557423194949">"পৰীক্ষা কৰি থকা হৈছে…"</string> <string name="ext_media_status_mounted" msgid="7253821726503179202">"সাজু"</string> <string name="ext_media_status_mounted_ro" msgid="8020978752406021015">"ৰীড-অনলি"</string> - <string name="ext_media_status_bad_removal" msgid="8395398567890329422">"বিপজ্জনকভাৱে আঁতৰোৱা হ\'ল"</string> + <string name="ext_media_status_bad_removal" msgid="8395398567890329422">"বিপজ্জনকভাৱে আঁতৰোৱা হ’ল"</string> <string name="ext_media_status_unmountable" msgid="805594039236667894">"ব্যৱহাৰযোগ্য নহয়"</string> <string name="ext_media_status_unsupported" msgid="4691436711745681828">"সঞ্চয়াগাৰ ব্যৱহাৰ কৰিব নোৱাৰি"</string> <string name="ext_media_status_ejecting" msgid="5463887263101234174">"বাহিৰলৈ উলিয়াই থকা হৈছে…"</string> @@ -1409,7 +1418,7 @@ <string name="ime_action_search" msgid="658110271822807811">"অনুসন্ধান কৰক"</string> <string name="ime_action_send" msgid="2316166556349314424">"পঠিয়াওক"</string> <string name="ime_action_next" msgid="3138843904009813834">"পৰৱৰ্তী"</string> - <string name="ime_action_done" msgid="8971516117910934605">"সম্পন্ন হ\'ল"</string> + <string name="ime_action_done" msgid="8971516117910934605">"সম্পন্ন হ’ল"</string> <string name="ime_action_previous" msgid="1443550039250105948">"আগৰ"</string> <string name="ime_action_default" msgid="2840921885558045721">"কার্য কৰক"</string> <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> ব্যৱহাৰ কৰি \n নম্বৰটো ডায়েল কৰক"</string> @@ -1437,7 +1446,7 @@ <string name="vpn_text" msgid="1610714069627824309">"নেটৱর্ক পৰিচালনা কৰিবলৈ টিপক।"</string> <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g>ৰ সৈতে সংযোগ হৈছে। নেটৱর্ক পৰিচালনা কৰিবলৈ টিপক।"</string> <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"সদা-সক্ৰিয় ভিপিএন সংযোগ কৰি থকা হৈছে…"</string> - <string name="vpn_lockdown_connected" msgid="8202679674819213931">"সদা-সক্ৰিয় ভিপিএন সংযোগ কৰা হ\'ল"</string> + <string name="vpn_lockdown_connected" msgid="8202679674819213931">"সদা-সক্ৰিয় ভিপিএন সংযোগ কৰা হ’ল"</string> <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"সদা-সক্ৰিয় ভিপিএনৰ লগত সংযোগ বিচ্ছিন্ন কৰা হৈছে"</string> <string name="vpn_lockdown_error" msgid="3133844445659711681">"সদা-সক্ৰিয় ভিপিএনৰ লগত সংযোগ কৰিব পৰা নাই"</string> <string name="vpn_lockdown_config" msgid="8151951501116759194">"নেটৱৰ্ক বা ভিপিএন ছেটিংসমূহ সলনি কৰক"</string> @@ -1460,7 +1469,7 @@ <item quantity="one"><xliff:g id="TOTAL">%d</xliff:g>ৰ <xliff:g id="INDEX">%d</xliff:g>টা</item> <item quantity="other"><xliff:g id="TOTAL">%d</xliff:g>ৰ <xliff:g id="INDEX">%d</xliff:g>টা</item> </plurals> - <string name="action_mode_done" msgid="7217581640461922289">"সম্পন্ন হ\'ল"</string> + <string name="action_mode_done" msgid="7217581640461922289">"সম্পন্ন হ’ল"</string> <string name="progress_erasing" msgid="2569962663843586562">"শ্বেয়াৰ কৰি থোৱা সঞ্চয়াগাৰ মচি থকা হৈছে…"</string> <string name="share" msgid="1778686618230011964">"শ্বেয়াৰ কৰক"</string> <string name="find" msgid="4808270900322985960">"বিচাৰক"</string> @@ -1472,7 +1481,7 @@ <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)এ অনুৰোধ কৰিছে"</string> <string name="gpsVerifYes" msgid="2346566072867213563">"হয়"</string> <string name="gpsVerifNo" msgid="1146564937346454865">"নহয়"</string> - <string name="sync_too_many_deletes" msgid="5296321850662746890">"মচি পেলোৱাৰ সীমা পাৰ হ\'ল"</string> + <string name="sync_too_many_deletes" msgid="5296321850662746890">"মচি পেলোৱাৰ সীমা পাৰ হ’ল"</string> <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"এই <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> ৰ মচি থোৱা <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> টা <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> বস্তু আছে। আপুনি কি কৰিব বিচাৰে?"</string> <string name="sync_really_delete" msgid="2572600103122596243">"বস্তুবোৰ মচক"</string> <string name="sync_undo_deletes" msgid="2941317360600338602">"মচা কাৰ্যক আনডু কৰক"</string> @@ -1501,7 +1510,7 @@ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string> <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"বাতিল কৰক"</string> <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"মচক"</string> - <string name="keyboardview_keycode_done" msgid="1992571118466679775">"সম্পন্ন হ\'ল"</string> + <string name="keyboardview_keycode_done" msgid="1992571118466679775">"সম্পন্ন হ’ল"</string> <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ম\'ড সলনি"</string> <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"শ্বিফ্ট"</string> <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"এণ্টাৰ"</string> @@ -1525,15 +1534,15 @@ <string name="extract_edit_menu_button" msgid="8940478730496610137">"সম্পাদনা কৰক"</string> <string name="data_usage_warning_title" msgid="6499834033204801605">"ডেটা সকীয়নি"</string> <string name="data_usage_warning_body" msgid="7340198905103751676">"আপুনি <xliff:g id="APP">%s</xliff:g> ডেটা ব্যৱহাৰ কৰিছে"</string> - <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"ম\'বাইল ডেটা ব্যৱাহৰৰ সীমা শেষ হৈছে"</string> + <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"ম’বাইল ডেটা ব্যৱাহৰৰ সীমা শেষ হৈছে"</string> <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"ৱাই-ফাই ডেটাৰ সীমাত উপনীত হৈছে"</string> <string name="data_usage_limit_body" msgid="2908179506560812973">"আপোনাৰ ডেটা চক্ৰৰ বাকী অংশৰ বাবে ডেটা পজ কৰা হৈছে"</string> - <string name="data_usage_mobile_limit_snoozed_title" msgid="3171402244827034372">"ম\'বাইল ডেটাৰ সীমা পাৰ কৰিছে"</string> + <string name="data_usage_mobile_limit_snoozed_title" msgid="3171402244827034372">"ম’বাইল ডেটাৰ সীমা পাৰ কৰিছে"</string> <string name="data_usage_wifi_limit_snoozed_title" msgid="3547771791046344188">"ৱাই-ফাই ডেটাৰ সীমা পাৰ কৰিছে"</string> <string name="data_usage_limit_snoozed_body" msgid="1671222777207603301">"আপুনি নিৰ্ধাৰিত সীমাতকৈ <xliff:g id="SIZE">%s</xliff:g> অধিক ব্যৱহাৰ কৰিছে"</string> <string name="data_usage_restricted_title" msgid="5965157361036321914">"নেপথ্য ডেটা সীমিত কৰি ৰখা হৈছে৷"</string> <string name="data_usage_restricted_body" msgid="469866376337242726">"সীমাবদ্ধতা আঁতৰাবলৈ টিপক।"</string> - <string name="data_usage_rapid_title" msgid="1809795402975261331">"অত্যধিক ম\'বাইল ডেটাৰ ব্যৱহাৰ"</string> + <string name="data_usage_rapid_title" msgid="1809795402975261331">"অত্যধিক ম’বাইল ডেটাৰ ব্যৱহাৰ"</string> <string name="data_usage_rapid_body" msgid="6897825788682442715">"আপোনাৰ এপসমূহে সচৰাচৰতকৈ অধিক ডেটা ব্যৱহাৰ কৰিছে"</string> <string name="data_usage_rapid_app_body" msgid="5396680996784142544">"<xliff:g id="APP">%s</xliff:g>এ সচৰাচৰতকৈ অধিক ডেটা ব্যৱহাৰ কৰিছে"</string> <string name="ssl_certificate" msgid="6510040486049237639">"নিৰাপত্তা সম্পৰ্কীয় প্ৰমাণপত্ৰ"</string> @@ -1568,7 +1577,7 @@ <string name="default_audio_route_name_usb" msgid="1234984851352637769">"ইউএছবি"</string> <string name="default_audio_route_category_name" msgid="3722811174003886946">"ছিষ্টেম"</string> <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ব্লুটুথ অডিঅ\'"</string> - <string name="wireless_display_route_description" msgid="9070346425023979651">"ৱায়াৰলেচ ডিছপ্লে\'"</string> + <string name="wireless_display_route_description" msgid="9070346425023979651">"ৱায়াৰলেচ ডিছপ্লে’"</string> <string name="media_route_button_content_description" msgid="591703006349356016">"কাষ্ট"</string> <string name="media_route_chooser_title" msgid="1751618554539087622">"ডিভাইচৰ লগত সংযোগ কৰক"</string> <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ডিভাইচত স্ক্ৰীণ কাষ্ট কৰক"</string> @@ -1732,11 +1741,11 @@ <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string> <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"অজ্ঞাত প\'ৰ্ট্ৰেইট"</string> <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"অজ্ঞাত লেণ্ডস্কেইপ"</string> - <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"বাতিল কৰা হ\'ল"</string> + <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"বাতিল কৰা হ’ল"</string> <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"সমল লিখাত আসোঁৱাহ"</string> <string name="reason_unknown" msgid="6048913880184628119">"অজ্ঞাত"</string> <string name="reason_service_unavailable" msgid="7824008732243903268">"প্ৰিণ্টিং সেৱা সক্ষম নহয়"</string> - <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> সেৱা ইনষ্টল কৰা হ\'ল"</string> + <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> সেৱা ইনষ্টল কৰা হ’ল"</string> <string name="print_service_installed_message" msgid="5897362931070459152">"সক্ষম কৰিবলৈ টিপক"</string> <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"প্ৰশাসকৰ পিন দিয়ক"</string> <string name="restr_pin_enter_pin" msgid="3395953421368476103">"পিন দিয়ক"</string> @@ -1755,14 +1764,14 @@ <string name="immersive_cling_title" msgid="8394201622932303336">"স্ক্ৰীণ পূৰ্ণৰূপত চাই আছে"</string> <string name="immersive_cling_description" msgid="3482371193207536040">"বাহিৰ হ\'বলৈ ওপৰৰপৰা তললৈ ছোৱাইপ কৰক।"</string> <string name="immersive_cling_positive" msgid="5016839404568297683">"বুজি পালোঁ"</string> - <string name="done_label" msgid="2093726099505892398">"সম্পন্ন কৰা হ\'ল"</string> + <string name="done_label" msgid="2093726099505892398">"সম্পন্ন কৰা হ’ল"</string> <string name="hour_picker_description" msgid="6698199186859736512">"ঘড়ীৰ বৃত্তাকাৰ শ্লাইডাৰ"</string> <string name="minute_picker_description" msgid="8606010966873791190">"মিনিটৰ বৃত্তাকাৰ শ্লাইডাৰ"</string> <string name="select_hours" msgid="6043079511766008245">"ঘণ্টা বাছনি কৰক"</string> <string name="select_minutes" msgid="3974345615920336087">"মিনিট বাছনি কৰক"</string> <string name="select_day" msgid="7774759604701773332">"মাহ আৰু দিন বাছনি কৰক"</string> <string name="select_year" msgid="7952052866994196170">"বছৰ বাছনি কৰক"</string> - <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> মচা হ\'ল"</string> + <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> মচা হ’ল"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"কৰ্মস্থান <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"২য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"৩য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string> @@ -1774,7 +1783,7 @@ <string name="package_deleted_device_owner" msgid="2307122077550236438">"আপোনাৰ প্ৰশাসকে মচিছে"</string> <string name="battery_saver_description_with_learn_more" msgid="6323937147992667707">"আপোনাৰ বেটাৰিৰ অৱস্থা উন্নত কৰিবলৈ বেটাৰি সঞ্চয়কাৰীয়ে ডিভাইচৰ কিছুমান সুবিধা অফ কৰে আৰু এপসমূহক সীমিত কৰে। "<annotation id="url">"অধিক জানক"</annotation></string> <string name="battery_saver_description" msgid="769989536172631582">"আপোনাৰ বেটাৰিৰ অৱস্থা উন্নত কৰিবলৈ বেটাৰি সঞ্চয়কাৰীয়ে ডিভাইচৰ কিছুমান সুবিধা অফ কৰে আৰু এপসমূহক সীমিত কৰে।"</string> - <string name="data_saver_description" msgid="6015391409098303235">"ডেটা ব্য়ৱহাৰ মাত্ৰা কম কৰিবৰ বাবে ডেটা সঞ্চয়কাৰীয়ে কিছুমান এপক নেপথ্য়ত ডেটা প্ৰেৰণ বা সংগ্ৰহ কৰাত বাধা প্ৰদান কৰে। আপুনি বৰ্তমান ব্য়ৱহাৰ কৰি থকা এটা এপে ডেটা ব্য়ৱহাৰ কৰিব পাৰে, কিন্তু সঘনাই এই কার্য কৰিব নোৱাৰিব পাৰে। ইয়াৰ অৰ্থ এইয়ে হ\'ব পাৰে যে, উদাহৰণস্বৰূপে, আপুনি নিটিপা পর্যন্ত প্ৰতিচ্ছবিসমূহ দেখুওৱা নহ\'ব।"</string> + <string name="data_saver_description" msgid="6015391409098303235">"ডেটা ব্য়ৱহাৰ মাত্ৰা কম কৰিবৰ বাবে ডেটা সঞ্চয়কাৰীয়ে কিছুমান এপক নেপথ্য়ত ডেটা প্ৰেৰণ বা সংগ্ৰহ কৰাত বাধা প্ৰদান কৰে। আপুনি বৰ্তমান ব্য়ৱহাৰ কৰি থকা এটা এপে ডেটা ব্য়ৱহাৰ কৰিব পাৰে, কিন্তু সঘনাই এই কার্য কৰিব নোৱাৰিব পাৰে। ইয়াৰ অৰ্থ এইয়ে হ\'ব পাৰে যে, উদাহৰণস্বৰূপে, আপুনি নিটিপা পর্যন্ত প্ৰতিচ্ছবিসমূহ দেখুওৱা নহ’ব।"</string> <string name="data_saver_enable_title" msgid="4674073932722787417">"ডেটা সঞ্চয়কাৰী অন কৰিবনে?"</string> <string name="data_saver_enable_button" msgid="7147735965247211818">"অন কৰক"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> @@ -1824,14 +1833,14 @@ <string name="muted_by" msgid="5942954724562097128">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>এ কিছুমান ধ্বনি মিউট কৰি আছে"</string> <string name="system_error_wipe_data" msgid="6608165524785354962">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে আৰু আপুনি ফেক্টৰী ডেটা ৰিছেট নকৰালৈকে ই সুস্থিৰভাৱে কাম নকৰিব পাৰে।"</string> <string name="system_error_manufacturer" msgid="8086872414744210668">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে। সবিশেষ জানিবৰ বাবে আপোনাৰ ডিভাইচ নির্মাতাৰ সৈতে যোগাযোগ কৰক।"</string> - <string name="stk_cc_ussd_to_dial" msgid="5214333646366591205">"USSD অনুৰোধ নিয়মীয়া কললৈ সলনি কৰা হ\'ল"</string> - <string name="stk_cc_ussd_to_ss" msgid="4884994189414782605">"USSD অনুৰোধ SS অনুৰোধলৈ সলনি কৰা হ\'ল"</string> - <string name="stk_cc_ussd_to_ussd" msgid="5728637484565449312">"নতুন USSD অনুৰোধলৈ সলনি কৰা হ\'ল"</string> - <string name="stk_cc_ussd_to_dial_video" msgid="4134455726513175559">"USSD SS অনুৰোধ ভিডিঅ\' কললৈ সলনি কৰা হ\'ল"</string> - <string name="stk_cc_ss_to_dial" msgid="1360775164651754978">"SS অনুৰোধ নিয়মীয়া কললৈ সলনি কৰা হ\'ল"</string> - <string name="stk_cc_ss_to_dial_video" msgid="6577956662913194947">"SS অনুৰোধ ভিডিঅ\' কললৈ সলনি কৰা হ\'ল"</string> - <string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS অনুৰোধ USSD অনুৰোধলৈ সলনি কৰা হ\'ল"</string> - <string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"নতুন SS অনুৰোধলৈ সলনি কৰা হ\'ল"</string> + <string name="stk_cc_ussd_to_dial" msgid="5214333646366591205">"USSD অনুৰোধ নিয়মীয়া কললৈ সলনি কৰা হ’ল"</string> + <string name="stk_cc_ussd_to_ss" msgid="4884994189414782605">"USSD অনুৰোধ SS অনুৰোধলৈ সলনি কৰা হ’ল"</string> + <string name="stk_cc_ussd_to_ussd" msgid="5728637484565449312">"নতুন USSD অনুৰোধলৈ সলনি কৰা হ’ল"</string> + <string name="stk_cc_ussd_to_dial_video" msgid="4134455726513175559">"USSD SS অনুৰোধ ভিডিঅ\' কললৈ সলনি কৰা হ’ল"</string> + <string name="stk_cc_ss_to_dial" msgid="1360775164651754978">"SS অনুৰোধ নিয়মীয়া কললৈ সলনি কৰা হ’ল"</string> + <string name="stk_cc_ss_to_dial_video" msgid="6577956662913194947">"SS অনুৰোধ ভিডিঅ\' কললৈ সলনি কৰা হ’ল"</string> + <string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS অনুৰোধ USSD অনুৰোধলৈ সলনি কৰা হ’ল"</string> + <string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"নতুন SS অনুৰোধলৈ সলনি কৰা হ’ল"</string> <string name="notification_work_profile_content_description" msgid="4600554564103770764">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string> <string name="notification_alerted_content_description" msgid="1296617716556420585">"সতৰ্ক কৰা হ’ল"</string> <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"বিস্তাৰ কৰক"</string> @@ -1846,8 +1855,8 @@ <string name="close_button_text" msgid="3937902162644062866">"বন্ধ কৰক"</string> <string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> <plurals name="selected_count" formatted="false" msgid="7187339492915744615"> - <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ\'ল</item> - <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ\'ল</item> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item> </plurals> <string name="default_notification_channel_label" msgid="5929663562028088222">"শ্ৰেণীবদ্ধ নকৰা"</string> <string name="importance_from_user" msgid="7318955817386549931">"এই জাননীবোৰৰ গুৰুত্ব আপুনি ছেট কৰব লাগিব।"</string> @@ -1867,8 +1876,8 @@ <string name="work_mode_off_title" msgid="1118691887588435530">"কৰ্মস্থানৰ প্ৰ\'ফাইল অন কৰিবনে?"</string> <string name="work_mode_off_message" msgid="5130856710614337649">"আপোনাৰ কৰ্মস্থানৰ এপসমূহ, জাননীসমূহ, ডেটা আৰু কৰ্মস্থানৰ প্ৰ\'ফাইলৰ অইন সুবিধাসমূহ অন কৰা হ\'ব"</string> <string name="work_mode_turn_on" msgid="2062544985670564875">"অন কৰক"</string> - <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"এই এপটো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে প্ৰস্তুত কৰা হৈছিল, আৰু ই বিচৰাধৰণে কাম নকৰিবও পাৰে। ইয়াৰ আপডেট আছে নেকি চাওক, বা বিকাশকৰ্তাৰ সৈতে যোগাযোগ কৰক।"</string> - <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"আপডেট আছে নেকি চাওক"</string> + <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"এই এপটো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে প্ৰস্তুত কৰা হৈছিল, আৰু ই বিচৰাধৰণে কাম নকৰিবও পাৰে। ইয়াৰ আপডে’ট আছে নেকি চাওক, বা বিকাশকৰ্তাৰ সৈতে যোগাযোগ কৰক।"</string> + <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"আপডে’ট আছে নেকি চাওক"</string> <string name="new_sms_notification_title" msgid="8442817549127555977">"আপুনি নতুন বার্তা লাভ কৰিছে"</string> <string name="new_sms_notification_content" msgid="7002938807812083463">"চাবলৈ এছএমএছ এপ্ খোলক"</string> <string name="user_encrypted_title" msgid="9054897468831672082">"কিছুমান কৰ্মক্ষমতা সীমিত হ\'ব পাৰে"</string> @@ -1884,7 +1893,7 @@ <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="5268556852031489931">"ডেম\' আৰম্ভ কৰি থকা হৈছে…"</string> <string name="demo_restarting_message" msgid="952118052531642451">"ডিভাইচটো আকৌ ছেটিং কৰি থকা হৈছে…"</string> - <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g>ক অক্ষম কৰা হ\'ল"</string> + <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g>ক অক্ষম কৰা হ’ল"</string> <string name="conference_call" msgid="3751093130790472426">"কনফাৰেঞ্চ কল"</string> <string name="tooltip_popup_title" msgid="5253721848739260181">"টুলটিপ"</string> <string name="app_category_game" msgid="5431836943981492993">"গেম"</string> @@ -1916,10 +1925,10 @@ <string name="autofill_save_title_with_type" msgid="2339135393607143594"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"ত <xliff:g id="TYPE">%1$s</xliff:g>ক ছেভ কৰিবনে?"</string> <string name="autofill_save_title_with_2types" msgid="87616102361154432"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"ত <xliff:g id="TYPE_0">%1$s</xliff:g> আৰু <xliff:g id="TYPE_1">%2$s</xliff:g>ক ছেভ কৰিবনে?"</string> <string name="autofill_save_title_with_3types" msgid="4108978552969604555"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"ত <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> আৰু <xliff:g id="TYPE_2">%3$s</xliff:g>ক ছেভ কৰিবনে?"</string> - <string name="autofill_update_title" msgid="5305781141104585279"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"ত আপডে\'ট কৰিবনে?"</string> - <string name="autofill_update_title_with_type" msgid="4624181147422762233"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"ত <xliff:g id="TYPE">%1$s</xliff:g> আপডে\'ট কৰিবনে?"</string> - <string name="autofill_update_title_with_2types" msgid="2300113827053626484"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"ত <xliff:g id="TYPE_0">%1$s</xliff:g> আৰু <xliff:g id="TYPE_1">%2$s</xliff:g> আপডে\'ট কৰিবনে?"</string> - <string name="autofill_update_title_with_3types" msgid="9089824354296211922">"এই তথ্যবোৰ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> আৰু <xliff:g id="TYPE_2">%3$s</xliff:g>ত আপডে\'ট কৰিবনে ?"</string> + <string name="autofill_update_title" msgid="5305781141104585279"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"ত আপডে’ট কৰিবনে?"</string> + <string name="autofill_update_title_with_type" msgid="4624181147422762233"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"ত <xliff:g id="TYPE">%1$s</xliff:g> আপডে’ট কৰিবনে?"</string> + <string name="autofill_update_title_with_2types" msgid="2300113827053626484"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"ত <xliff:g id="TYPE_0">%1$s</xliff:g> আৰু <xliff:g id="TYPE_1">%2$s</xliff:g> আপডে’ট কৰিবনে?"</string> + <string name="autofill_update_title_with_3types" msgid="9089824354296211922">"এই তথ্যবোৰ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> আৰু <xliff:g id="TYPE_2">%3$s</xliff:g>ত আপডে’ট কৰিবনে ?"</string> <string name="autofill_save_yes" msgid="6398026094049005921">"ছেভ কৰক"</string> <string name="autofill_save_no" msgid="2625132258725581787">"নালাগে, ধন্যবাদ"</string> <string name="autofill_update_yes" msgid="310358413273276958">"আপডে’ট কৰক"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 55966cffc63e..076ea8d70f37 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tətbiqə cihazın telefon funksiyalarına giriş icazəsi verir. Belə icazəli tətbiq bu telefonun nömrəsini və cihaz İD\'ni, zəngin aktiv olub-olmadığını və zəng edilən nömrəni müəyyən edə bilər."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"zəngləri sistem üzərindən yönləndirin"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Tətbiqə, zəng təcrübəsini yaxşılaşdırmaq üçün, zəngləri sistem üzərindən yönləndirməyə icazə verilir."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"zənglərə sistemdə baxın və nəzarət edin."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Tətbiqin cihazda davam edən zəngləri görməsinə və nəzarət etməsinə icazə verin. Bura zəng edən nömrələr və zənglərin statusu haqqında məlumat daxildir."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"zəngə digər tətbiqdən davam edin"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Tətbiqə digər tətbiqdə başlayan zəngə davam etmək icazəsi verilir."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"telefon nömrələrini oxuyun"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Tətbiqə Yaxın Məsafə Kommunikasiyası (NFC) teqləri, kartları və oxuyucuları ilə əlaqə qurmağa icazə verir."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Ekran kilidini deaktiv edir"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tətbiqə kilid açarını və təhlükəsizlik parolunu deaktiv etməyə imkan verir. Qanuni misal budur ki, telefon zəng qəbul edən zaman kilidi açır və zəng qurtarandan sonra kilidi bağlayır."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ekran kilidi mürəkkəbliliyini əldə edin və tələb edin"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Tətbiqə ekran kilidinin uzunluq intervalı və növünü göstərən ekran kilidi mürəkkəbliliyini (yüksək, orta, aşağı və ya heçbiri) öyrənməyə icazə verir. Tətbiq, istifadəçilərə ekran kilidini müəyyən səviyyəyə yeniləməyi təklif edə bilər, lakin istifadəçilər istənilən vaxt bunu iqnor edə bilər. Nəzərə alın ki, ekran kilidi şifrələndiyinə görə tətbiq parolu dəqiq bilmir."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrik proqramdan istifadə edin"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Doğrulama üçün biometrik proqramdan istifadə etməyə imkan verir"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"barmaq izi avadanlığını idarə edin"</string> @@ -1083,23 +1087,23 @@ <string name="deleteText" msgid="6979668428458199034">"Sil"</string> <string name="inputMethod" msgid="1653630062304567879">"Daxiletmə metodu"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Mətn əməliyyatları"</string> - <string name="email" msgid="4560673117055050403">"E-poçt"</string> + <string name="email" msgid="4560673117055050403">"E-poçtu aç"</string> <string name="email_desc" msgid="3638665569546416795">"Seçilmiş ünvana e-məktub yazın"</string> - <string name="dial" msgid="1253998302767701559">"Zəng"</string> + <string name="dial" msgid="1253998302767701559">"Zəng edin"</string> <string name="dial_desc" msgid="6573723404985517250">"Seçilmiş telefon nömrəsinə zəng edin"</string> - <string name="map" msgid="5441053548030107189">"Xəritə"</string> + <string name="map" msgid="5441053548030107189">"Xəritəni aç"</string> <string name="map_desc" msgid="1836995341943772348">"Seçilmiş ünvanları tapın"</string> <string name="browse" msgid="1245903488306147205">"Açın"</string> <string name="browse_desc" msgid="8220976549618935044">"Seçilmiş linki açın"</string> - <string name="sms" msgid="4560537514610063430">"Mesaj"</string> + <string name="sms" msgid="4560537514610063430">"Mesaj yazın"</string> <string name="sms_desc" msgid="7526588350969638809">"Seçilmiş telefon nömrəsini mesajla göndərin"</string> <string name="add_contact" msgid="7867066569670597203">"Əlavə edin"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Kontakta əlavə edin"</string> <string name="view_calendar" msgid="979609872939597838">"Baxın"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Təqvimdə seçilmiş vaxta baxın"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Cədvəl"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Təqvimdə planlayın"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Tədbiri seçilmiş vaxta planlaşdırın"</string> - <string name="view_flight" msgid="7691640491425680214">"Trek"</string> + <string name="view_flight" msgid="7691640491425680214">"İzləyin"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Seçilmiş uçuşu izləyin"</string> <string name="translate" msgid="9218619809342576858">"Tərcümə edin"</string> <string name="translate_desc" msgid="4502367770068777202">"Seçilmiş mətni tərcümə edin"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Planşet yenilənir…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Cihaz yenilənir…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon başlayır…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android işə başlayır..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Planşet başlayır…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Cihaz başlayır…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Yaddaş optimallaşdırılır."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Bütün şəbəkələr"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> tərəfindən təklif edilən Wi‑Fi şəbəkəsinə qoşuldu"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> tərəfindən şəbəkələrin təklif edilməsinə icazə vermək itəyirsiniz?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Bəli"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Xeyr"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik olaraq aktiv ediləcək"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Yadda saxlanmış yüksək keyfiyyətli şəbəkələr yaxınlıqda olduqda"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Yenidən aktiv etməyin"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 9c45ba888577..0a94acfe9364 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -450,6 +450,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Dozvoljava aplikaciji da pristupa funkcijama telefona na uređaju. Ova dozvola omogućava aplikaciji da utvrdi broj telefona i ID-ove uređaja, zatim da li je poziv aktivan, kao i broj daljinskog uređaja sa kojim je uspostavljen poziv."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"preusmeravanje poziva preko sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dozvoljava aplikaciji da preusmerava pozive preko sistema da bi poboljšala doživljaj pozivanja."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"pregled i kontrola poziva preko sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Dozvoljava aplikaciji da pregleda i kontroliše trenutne pozive na uređaju. To obuhvata informacije poput brojeva telefona i statusa poziva."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"nastavi poziv u drugoj aplikaciji"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Dozvoljava aplikaciji da nastavi poziv koji je započet u drugoj aplikaciji."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje brojeva telefona"</string> @@ -510,6 +512,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Dozvoljava aplikaciji da komunicira sa oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja ekrana"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Dozvoljava aplikaciji da onemogući zaključavanje tastature i sve povezane bezbednosne mere sa lozinkama. Na primer, telefon onemogućava zaključavanje tastature pri prijemu dolaznog telefonskog poziva, a zatim ga ponovo omogućava po završetku poziva."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"dobijanje i traženje nivoa složenosti zaključavanja ekrana"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju zaključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za zaključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"koristi biometrijski hardver"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu identiteta"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljaj hardverom za otiske prstiju"</string> @@ -1107,7 +1111,7 @@ <string name="email_desc" msgid="3638665569546416795">"Pošaljite imejl na izabranu adresu"</string> <string name="dial" msgid="1253998302767701559">"Pozovi"</string> <string name="dial_desc" msgid="6573723404985517250">"Pozovite izabrani broj telefona"</string> - <string name="map" msgid="5441053548030107189">"Mapa"</string> + <string name="map" msgid="5441053548030107189">"Prikaži na mapi"</string> <string name="map_desc" msgid="1836995341943772348">"Pronađite izabranu adresu"</string> <string name="browse" msgid="1245903488306147205">"Otvori"</string> <string name="browse_desc" msgid="8220976549618935044">"Otvorite izabrani URL"</string> @@ -1201,6 +1205,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet se ažurira…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Uređaj se ažurira…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon se pokreće…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android se pokreće…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet se pokreće…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Uređaj se pokreće…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Memorija se optimizuje."</string> @@ -1261,6 +1266,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da biste videli sve mreže"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Povezani ste sa Wi‑Fi mrežom koju predlaže <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Želite li da dozvolite da vam <xliff:g id="NAME">%s</xliff:g> predlaže mreže?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se automatski uključiti"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini sačuvane mreže visokog kvaliteta"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne uključuj ponovo"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 930feba12830..cfe076deb8ec 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дазваляе прыкладанням атрымлiваць доступ да функцый тэлефона на прыладзе. Дзякуючы гэтаму дазволу прыкладанне можа вызначаць iдэнтыфiкатары нумару тэлефона i прылады, незалежна ад таго, цi актыўны выклiк, i аддалены нумар, на якi робiцца выклiк."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"перанакіраванне выклікаў праз сістэму"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дазваляе праграме перанакіроўваць выклікі праз сістэму ў мэтах паляпшэння выклікаў."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"праглядаць выклікі і кіраваць імі праз сістэму."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Дазваляе праграме праглядаць на прыладзе ўваходныя выклікі і кіраваць імі. Гэта інфармацыя ўключае нумары выклікаў і звесткі пра іх краіну."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"працяг выкліку з іншай праграмы"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Дазваляе праграме працягваць выклік, які пачаўся ў іншай праграме."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"счытваць нумары тэлефонаў"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Дазваляе прыкладаннzv спалучацца з тэгамі, картамі і счытваючымі прыладамі Near Field Communication (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"адключэнне блакiроўкi экрана"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дазваляе прыкладанням адключаць блакiроўку клавіятуры і любыя сродкі абароны, звязаныя з паролем. Прыкладам гэтага з\'яўляецца адключэнне тэлефонам блакiроўкi клавіятуры пры атрыманні ўваходнага выкліку і паўторнае ўключэнне блакiроўкi клавіятуры, калі выклік завершаны."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"атрымліваць і адсылаць запыты наконт узроўню складанасці блакіроўкі экрана"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Дазваляе праграме вызначаць узровень складанасці блакіроўкі экрана (высокі, сярэдні, нізкі ці нулявы), які залежыць ад даўжыні пароля і ад тыпу блакіроўкі экрана. Праграма можа прапанаваць карыстальнікам ускладніць блакіроўку экрана, аднак гэту прапанову можна ігнараваць. Заўважце, што праграма не можа ведаць тып і пароль блакіроўкі экрана, таму што яны захоўваюцца ў зашыфраваным выглядзе."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"выкарыстоўваць біяметрычнае абсталяванне"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дазваляе праграме выкарыстоўваць для аўтэнтыфікацыі біяметрычнае абсталяванне"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"кіраваць апаратнымі сродкамі для адбіткаў пальцаў"</string> @@ -1123,21 +1127,21 @@ <string name="deleteText" msgid="6979668428458199034">"Выдалiць"</string> <string name="inputMethod" msgid="1653630062304567879">"Метад уводу"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string> - <string name="email" msgid="4560673117055050403">"Электронная пошта"</string> + <string name="email" msgid="4560673117055050403">"Напісаць ліст"</string> <string name="email_desc" msgid="3638665569546416795">"Напісаць электронны ліст на выбраны адрас"</string> <string name="dial" msgid="1253998302767701559">"Выклікаць"</string> <string name="dial_desc" msgid="6573723404985517250">"Звязацца з абанентам"</string> - <string name="map" msgid="5441053548030107189">"Карта"</string> + <string name="map" msgid="5441053548030107189">"Адкрыць карту"</string> <string name="map_desc" msgid="1836995341943772348">"Паказаць выбраны адрас на карце"</string> <string name="browse" msgid="1245903488306147205">"Адкрыць"</string> <string name="browse_desc" msgid="8220976549618935044">"Адкрыць URL у браўзеры"</string> - <string name="sms" msgid="4560537514610063430">"Паведамленне"</string> + <string name="sms" msgid="4560537514610063430">"Напісаць SMS"</string> <string name="sms_desc" msgid="7526588350969638809">"Адправіць паведамленне на выбраны нумар"</string> <string name="add_contact" msgid="7867066569670597203">"Дадаць"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Дадаць у кантакты"</string> <string name="view_calendar" msgid="979609872939597838">"Прагледзець"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Паказаць выбраны час у календары"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Графік"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Запланаваць"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Запланаваць падзею ў выбраны час"</string> <string name="view_flight" msgid="7691640491425680214">"Сачыць"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Адсочваць рэйс"</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Абнаўленне планшэта…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Абнаўленне прылады…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Запуск тэлефона…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android запускаецца..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Запуск планшэта…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Запуск прылады…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Аптымізацыя сховішча."</string> @@ -1283,6 +1288,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="1524719325616630906">"Падключана да сеткі Wi‑Fi, прапанаванай праграмай \"<xliff:g id="NAME">%s</xliff:g>\""</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Хочаце дазволіць праграме \"<xliff:g id="NAME">%s</xliff:g>\" прапаноўваць вам сеткі?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Побач з захаванай сеткай з высакаякасным сігналам"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не ўключаць зноў"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index d2857e8be03b..8897baca2808 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Разрешава на приложението достъп до телефонните функции на устройството. Това разрешение позволява на приложението да определя телефонния номер и идентификационния номер на устройството, дали се води разговор и отдалечения номер, до който е установена връзка с обаждането."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"маршрутизиране на обажданията чрез системата"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Разрешава на приложението да маршрутизира обажданията си чрез системата с цел подобряване на свързаната с тях практическа работа."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"вижда и управлява обажданията чрез системата."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Разрешава на приложението да вижда и управлява текущите обаждания на устройството. Това включва различна информация, като например номерата и състоянието на обажданията."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"продължаване на обаждане от друго приложение"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Разрешава на приложението да продължи обаждане, стартирано в друго приложение."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"четене на телефонните номера"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"получаване и заявяване на сложността на опцията за заключване на екрана"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Разрешава на приложението да разбере нивото на сложност на опцията за заключване на екрана (високо, средно, ниско или липса на такова), което указва възможния диапазон на дължината и типа на опцията. Приложението може също да предложи на потребителите да актуализират опцията за заключване на екрана до определено ниво, но те могат да пренебрегнат това и да излязат от него. Обърнете внимание, че опцията за заключване на екрана не се съхранява като обикновен текст, така че приложението не знае точната парола."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"използване на хардуера за биометрични данни"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Разрешава на приложението да използва хардуера за биометрични данни с цел удостоверяване"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управление на хардуера за отпечатъци"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Таблетът се актуализира…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Устройството се актуализира…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Телефонът се стартира…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android се стартира…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Таблетът се стартира…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Устройството се стартира…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Хранилището се оптимизира."</string> @@ -1239,6 +1244,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="1524719325616630906">"Установена е връзка с Wi‑Fi мрежа, предложена от <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Искате ли да разрешите на <xliff:g id="NAME">%s</xliff:g> да ви предлага мрежи?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Когато сте в района на запазена мрежа с високо качество"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Без повторно включване"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 80eefc44ea96..26a3ba0c269c 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -318,7 +318,7 @@ <string name="permgroupdesc_visual" msgid="3415827902566663546">"আপনার ফটো ও ভিডিও অ্যাক্সেস করুন"</string> <string name="permgrouprequest_visual" msgid="6907523945030290376">"আপনার ফটো ও ভিডিওতে <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-কে অ্যাক্সেস দেবেন?"</string> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"উইন্ডোর কন্টেন্ট পুনরুদ্ধার করে"</string> - <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপনি ইন্টারঅ্যাক্ট করছেন এমন একটি উইন্ডোর সামগ্রীকে সযত্নে নিরীক্ষণ করে৷"</string> + <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ব্যবহার করছেন এমন একটি উইন্ডোর কন্টেন্ট নিরীক্ষণ করে৷"</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পর্শের মাধ্যমে অন্বেষণ করা চালু করুন"</string> <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"যে আইটেমগুলিতে আলতো চেপেছেন সেগুলি সশব্দে বলবে এবং ইঙ্গিতগুলি ব্যবহার করে স্ক্রিন অন্বেষণ করা যাবে৷"</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"আপনার লেখা পাঠ্যকে নিরীক্ষণ করে"</string> @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"অ্যাপ্লিকেশানটিকে ডিভাইসের ফোন বৈশিষ্ট্যগুলিকে অ্যাক্সেস করার অনুমতি দেয়৷ এই অনুমতিটি অ্যাপ্লিকেশানটিকে একটি কল সক্রিয় থাকা অবস্থায় এবং দূরবর্তী নম্বর একটি কল দ্বারা সংযুক্ত থাকাকালীনও ফোন নম্বর এবং ডিভাইসের IDগুলি নির্ধারণ করার অনুমতি দেয়৷"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"সিস্টেমের মাধ্যমে কলগুলি রুট করতে দিন"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"কল করার অভিজ্ঞতা উন্নত করার জন্য অ্যাপকে সিস্টেমের মাধ্যমে তার কলগুলি রুট করতে দেয়।"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"সিস্টেমের মাধ্যমে কল দেখা এবং নিয়ন্ত্রণ করা।"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ডিভাইসে চালু আছে এমন কল দেখতে এবং নিয়ন্ত্রণ করতে অ্যাপকে অনুমতি দেয়। কল করা হচ্ছে যে নম্বরে সেটি এবং কলের স্ট্যাটাস কী সেই সব তথ্য এতে অন্তর্ভুক্ত।"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"অন্য কোনও অ্যাপ দিয়ে করে থাকা কল চালিয়ে যান"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"অন্য কোনও অ্যাপ দিয়ে কল করলে এই অ্যাপটিকে সেটি চালিয়ে যেতে দেয়।"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ফোন নম্বরগুলি পড়া হোক"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"স্ক্রিন লক কমপ্লেক্সিটি প্যাটার্নটির জন্য অনুরোধ জানান এবং ব্যবহার করুন"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"স্ক্রিন লক কমপ্লেক্সিটি প্যাটার্নটির লেভেল (বেশি, মাঝারি, কম বা কোনও কিছুই নেই) জানতে অ্যাপকে অনুমতি দিন, যা সম্ভাব্য স্ক্রিন লকের ধরন এবং তা কতটা দীর্ঘ হবে তার ইঙ্গিত দেয়। একটি নির্দিষ্ট লেভেল পর্যন্ত স্ক্রিন লক আপডেট করা যাবে তাও এই অ্যাপটি সাজেস্ট করতে পারে, তবে ব্যবহারকারীর তা উপেক্ষা করার এবং অন্য কোথাও চলে যাওয়ার স্বাধীনতা আছে। মনে রাখবেন প্লেনটেক্সটে স্ক্রিন লক স্টোর করা হয় না, তাই সঠিক পাসওয়ার্ড অ্যাপের পক্ষে জানা সম্ভব নয়।"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করুন"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"অ্যাপটিকে যাচাইকরণের জন্য বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করার অনুমতি দেয়"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার পরিচালনা করুন"</string> @@ -1083,23 +1087,23 @@ <string name="deleteText" msgid="6979668428458199034">"মুছুন"</string> <string name="inputMethod" msgid="1653630062304567879">"ইনপুট পদ্ধতি"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"পাঠ্য ক্রিয়াগুলি"</string> - <string name="email" msgid="4560673117055050403">"ইমেল"</string> + <string name="email" msgid="4560673117055050403">"ইমেল করুন"</string> <string name="email_desc" msgid="3638665569546416795">"বেছে নেওয়া আইডিতে ইমেল পাঠান"</string> - <string name="dial" msgid="1253998302767701559">"কল"</string> + <string name="dial" msgid="1253998302767701559">"কল খুলুন"</string> <string name="dial_desc" msgid="6573723404985517250">"বেছে নেওয়া ফোন নম্বরে কল করুন"</string> - <string name="map" msgid="5441053548030107189">"ম্যাপ"</string> + <string name="map" msgid="5441053548030107189">"ম্যাপ খুলুন"</string> <string name="map_desc" msgid="1836995341943772348">"বেছে নেওয়া ঠিকানাটি ম্যাপে দেখুন"</string> <string name="browse" msgid="1245903488306147205">"খুলুন"</string> - <string name="browse_desc" msgid="8220976549618935044">"বেছে নেওয়া ইউআরএলে যান"</string> - <string name="sms" msgid="4560537514610063430">"মেসেজ"</string> + <string name="browse_desc" msgid="8220976549618935044">"বেছে নেওয়া ইউআরএল-এ যান"</string> + <string name="sms" msgid="4560537514610063430">"মেসেজ করুন"</string> <string name="sms_desc" msgid="7526588350969638809">"বেছে নেওয়া ফোন নম্বরে মেসেজ পাঠান"</string> <string name="add_contact" msgid="7867066569670597203">"যোগ করুন"</string> <string name="add_contact_desc" msgid="4830217847004590345">"পরিচিতিতে যোগ করুন"</string> <string name="view_calendar" msgid="979609872939597838">"দেখুন"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"বেছে নেওয়া দিনটি ক্যালেন্ডারে দেখুন"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"সময়সূচি"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"সময়সূচি সেট করুন"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"বেছে নেওয়া সময়ে ইভেন্ট সেট করুন"</string> - <string name="view_flight" msgid="7691640491425680214">"ট্র্যাক"</string> + <string name="view_flight" msgid="7691640491425680214">"ট্র্যাক করুন"</string> <string name="view_flight_desc" msgid="3876322502674253506">"বেছে নেওয়া ফ্লাইট ট্র্যাক করুন"</string> <string name="translate" msgid="9218619809342576858">"অনুবাদ করুন"</string> <string name="translate_desc" msgid="4502367770068777202">"বেছে নেওয়া টেক্সট অনুবাদ করুন"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ট্যাবলেট আপডেট করা হচ্ছে…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ডিভাইস আপডেট করা হচ্ছে…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ফোন চালু করা হচ্ছে…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android চালু হচ্ছে…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ট্যাবলেট চালু করা হচ্ছে…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ডিভাইস চালু করা হচ্ছে…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"স্টোরেজ অপ্টিমাইজ করা হচ্ছে৷"</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g>-এর সাজেস্ট করা ওয়াই-ফাইয়ে নেটওয়ার্ক কানেক্ট করা হয়েছে"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"আপনি <xliff:g id="NAME">%s</xliff:g>-কে নেটওয়ার্ক সাজেস্ট করতে দিতে চান?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"যখন আপনি একটি উচ্চ মানের সংরক্ষিত নেটওয়ার্ক কাছাকাছি থাকেন"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"আবার চালু করবেন না"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 718cba44dbc6..e336cd0088d0 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -450,6 +450,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Omogućava aplikaciji pristup telefonskim funkcijama uređaja. Ovo odobrenje omogućava aplikaciji određivanje telefonskog i identifikacionog broja uređaja, bez obzira da li je poziv aktivan i da li je uspostavljena veza sa pozivanim brojem."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"usmjeravanje poziva preko sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dopušta aplikaciji da pozive usmjeri preko sistema radi poboljšanja iskustva pozivanja."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"vidjeti i kontrolirati pozive preko sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Dozvoljava aplikaciji da vidi i kontrolira odlazne pozive na uređaju. To uključuje informacije kao što su brojevi telefona i stanja poziva."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"nastavlja poziv iz druge aplikacije"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Dozvoljava aplikaciji nastavljanje poziva koji je započet u drugoj aplikaciji."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje telefonskih brojeva"</string> @@ -510,6 +512,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Dozvoljava aplikaciji komuniciranje sa NFC (komunikacija bliskog polja) oznakama, karticama i čitačima."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivacija zaključavanja ekrana"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Omogućava aplikaciji deaktivaciju zaključane tastature i svih povezanih zaštita. Naprimjer, telefon deaktivira zaključavanje tastature kod dolaznog telefonskog poziva, a zatim ponovo aktivira zaključavanje tastature kada je poziv završen."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"preuzimanje i traženje nivoa kompleksnosti zaključavanja ekrana"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Omogućava aplikaciji da sazna nivo kompleksnosti zaključavanja ekrana (visoki, srednji, niski ili bez zaključavanja), što naznačava mogući raspon trajanja i vrste zaključavanja ekrana. Aplikacija također može korisnicima predložiti da ažuriraju zaključavanje ekrana do određenog nivoa ali korisnici slobodno mogu ignorirati prijedlog i napustiti stranicu. Važno je napomenuti da se zaključavanje ekrana ne pohranjuje kao obični tekst tako da aplikacija ne zna tačnu lozinku."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"koristi biometrijski hardver za otiske prstij"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Omogućava aplikaciji da za autentifikaciju koristi biometrijski hardver"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje hardverom za otiske prstiju"</string> @@ -1103,28 +1107,28 @@ <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string> <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Akcije za tekst"</string> - <string name="email" msgid="4560673117055050403">"E-pošta"</string> - <string name="email_desc" msgid="3638665569546416795">"E-pošta odabrane adrese"</string> - <string name="dial" msgid="1253998302767701559">"Pozovite"</string> - <string name="dial_desc" msgid="6573723404985517250">"Pozovite odabrani broj telefona"</string> - <string name="map" msgid="5441053548030107189">"Mapa"</string> - <string name="map_desc" msgid="1836995341943772348">"Lociranje odabrane adrese"</string> - <string name="browse" msgid="1245903488306147205">"Otvorite"</string> - <string name="browse_desc" msgid="8220976549618935044">"Otvorite odabrani URL"</string> - <string name="sms" msgid="4560537514610063430">"Poruka"</string> - <string name="sms_desc" msgid="7526588350969638809">"Pošaljite poruku odabranom broju telefona"</string> - <string name="add_contact" msgid="7867066569670597203">"Dodajte"</string> + <string name="email" msgid="4560673117055050403">"Pošalji e-poruku"</string> + <string name="email_desc" msgid="3638665569546416795">"Pošalji e-poruku na odabranu adresu"</string> + <string name="dial" msgid="1253998302767701559">"Pozovi"</string> + <string name="dial_desc" msgid="6573723404985517250">"Pozovi odabrani broj telefona"</string> + <string name="map" msgid="5441053548030107189">"Prikaži na mapi"</string> + <string name="map_desc" msgid="1836995341943772348">"Lociraj odabranu adresu"</string> + <string name="browse" msgid="1245903488306147205">"Otvori"</string> + <string name="browse_desc" msgid="8220976549618935044">"Otvori odabrani URL"</string> + <string name="sms" msgid="4560537514610063430">"Pošalji SMS"</string> + <string name="sms_desc" msgid="7526588350969638809">"Pošalji SMS odabranom broju telefona"</string> + <string name="add_contact" msgid="7867066569670597203">"Dodaj"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Dodaj u kontakte"</string> <string name="view_calendar" msgid="979609872939597838">"Prikaži"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"Pogledajte odabrano vrijeme u kalendaru"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"Prikaži odabrano vrijeme u kalendaru"</string> <string name="add_calendar_event" msgid="1953664627192056206">"Zakaži"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"Zakažite događaj za odabrano vrijeme"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"Zakaži događaj za odabrano vrijeme"</string> <string name="view_flight" msgid="7691640491425680214">"Prati"</string> - <string name="view_flight_desc" msgid="3876322502674253506">"Pratite odabrani let"</string> + <string name="view_flight_desc" msgid="3876322502674253506">"Prati odabrani let"</string> <string name="translate" msgid="9218619809342576858">"Prevedi"</string> <string name="translate_desc" msgid="4502367770068777202">"Prevedi odabrani tekst"</string> - <string name="define" msgid="7394820043869954211">"Definirajte"</string> - <string name="define_desc" msgid="7910883642444919726">"Definiranje odabranog teksta"</string> + <string name="define" msgid="7394820043869954211">"Definiraj"</string> + <string name="define_desc" msgid="7910883642444919726">"Definiraj odabrani tekst"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke funkcije sistema možda neće raditi"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno prostora za sistem. Obezbijedite 250MB slobodnog prostora i ponovo pokrenite uređaj."</string> @@ -1203,6 +1207,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Ažuriranje tableta…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Ažuriranje uređaja…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Pokretanje telefona…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android se pokreće..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Pokretanje tableta…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Pokretanje uređaja…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje pohrane."</string> @@ -1263,6 +1268,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da vidite sve mreže"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Povežite se"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Povezani ste na WiFi mrežu koju je predložila aplikacija <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Želite li dozvoliti aplikaciji <xliff:g id="NAME">%s</xliff:g> da vam predlaže mreže?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi veza će se automatski uključiti"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini sačuvane mreže visokog kvaliteta"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nemoj ponovo uključiti"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index c68e5248a0e2..35c223b20fdc 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet que l\'aplicació accedeixi a les funcions de telèfon del dispositiu. Aquest permís permet que l\'aplicació determini el número de telèfon i els identificadors del dispositiu, si hi ha una trucada activa i el número remot connectat amb una trucada."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"encaminar trucades a través del sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permet que l\'aplicació encamini les trucades a través del sistema per millorar-ne l\'experiència."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"consulta i controla les trucades a través del sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permet que l\'aplicació consulti i controli les trucades en curs al dispositiu. Inclou informació com ara l\'estat i els números de les trucades."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"Continua una trucada d\'una altra aplicació"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permet que l\'aplicació continuï una trucada que s\'havia iniciat en una altra aplicació."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"llegir els números de telèfon"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"obtenir i sol·licitar el nivell de complexitat del bloqueig de pantalla"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"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> <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> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"Suprimeix"</string> <string name="inputMethod" msgid="1653630062304567879">"Mètode d\'introducció de text"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Accions de text"</string> - <string name="email" msgid="4560673117055050403">"Correu electrònic"</string> + <string name="email" msgid="4560673117055050403">"Envia un correu"</string> <string name="email_desc" msgid="3638665569546416795">"Envia un correu electrònic a l\'adreça seleccionada"</string> <string name="dial" msgid="1253998302767701559">"Truca"</string> <string name="dial_desc" msgid="6573723404985517250">"Truca al número de telèfon seleccionat"</string> @@ -1091,12 +1095,12 @@ <string name="map_desc" msgid="1836995341943772348">"Localitza l\'adreça seleccionada"</string> <string name="browse" msgid="1245903488306147205">"Obre"</string> <string name="browse_desc" msgid="8220976549618935044">"Obre l\'URL seleccionat"</string> - <string name="sms" msgid="4560537514610063430">"Missatge"</string> + <string name="sms" msgid="4560537514610063430">"Envia un SMS"</string> <string name="sms_desc" msgid="7526588350969638809">"Envia un SMS al número de telèfon seleccionat"</string> <string name="add_contact" msgid="7867066569670597203">"Afegeix"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Afegeix als contactes"</string> <string name="view_calendar" msgid="979609872939597838">"Mostra"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"Consulta l\'hora seleccionada al calendari"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"Consulta la data seleccionada al calendari"</string> <string name="add_calendar_event" msgid="1953664627192056206">"Programa"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Programa un esdeveniment per a la data seleccionada"</string> <string name="view_flight" msgid="7691640491425680214">"Fes un seguiment"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"La tauleta s\'està actualitzant…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"El dispositiu s\'està actualitzant…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"S\'està iniciant el telèfon…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"S\'està iniciant Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"S\'està iniciant la tauleta…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"S\'està iniciant el dispositiu…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"S\'està optimitzant l\'emmagatzematge."</string> @@ -1239,6 +1244,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="1524719325616630906">"T\'has connectat a la xarxa Wi‑Fi proposada per l\'aplicació <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Vols permetre que <xliff:g id="NAME">%s</xliff:g> et proposi xarxes?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quan siguis a prop d\'una xarxa de qualitat desada"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No tornis a activar"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 4758c07d5266..0061ca760857 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikaci získat přístup k telefonním funkcím zařízení. Toto oprávnění umožňuje aplikaci zjistit telefonní číslo telefonu, identifikační čísla zařízení, zda zrovna probíhá hovor, a vzdálené číslo, ke kterému je hovor připojen."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"směrování volání prostřednictvím systému"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Umožňuje aplikaci směrovat volání prostřednictvím systému za účelem vylepšení funkcí volání."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"zobrazení a ovládání hovorů v systému."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Umožňuje aplikaci zobrazit a ovládat probíhající hovory v zařízení. Zahrnuje to informace jako zúčastněna čísla a stav hovoru."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"pokračování v hovoru v jiné aplikaci"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Umožňuje aplikace pokračovat v hovoru, který byl zahájen v jiné aplikaci."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"přístup k telefonním číslům"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje aplikaci komunikovat se štítky, kartami a čtečkami s podporou technologie NFC."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"vypnutí zámku obrazovky"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje aplikaci vypnout zámek kláves a související zabezpečení heslem. Telefon například vypne zámek klávesnice při příchozím hovoru a po skončení hovoru jej zase zapne."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"zjišťování a vyžadování složitosti zámku obrazovky"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Umožňuje aplikaci zjistit úroveň složitosti zámku obrazovky (vysoká, střední, nízká nebo žádná), která ukazuje možnou délku a typ zámku obrazovky. Aplikace také může uživatelům navrhovat, aby zámek obrazovky upravili na určitou úroveň, ale uživatelé mohou návrhy klidně ignorovat a odejít. Zámek obrazovky není uložen jako prostý text, a tak aplikace přesné heslo nezná."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"použití biometrického hardwaru"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Umožňuje aplikaci použít k ověření biometrický hardware"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"správa hardwaru na čtení otisků prstů"</string> @@ -1131,7 +1135,7 @@ <string name="map_desc" msgid="1836995341943772348">"Vyhledat vybranou adresu"</string> <string name="browse" msgid="1245903488306147205">"Otevřít"</string> <string name="browse_desc" msgid="8220976549618935044">"Otevřít vybranou adresu URL"</string> - <string name="sms" msgid="4560537514610063430">"Zpráva"</string> + <string name="sms" msgid="4560537514610063430">"Napsat zprávu"</string> <string name="sms_desc" msgid="7526588350969638809">"Napsat SMS na vybrané telefonní číslo"</string> <string name="add_contact" msgid="7867066569670597203">"Přidat"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Přidat do kontaktů"</string> @@ -1144,7 +1148,7 @@ <string name="translate" msgid="9218619809342576858">"Přeložit"</string> <string name="translate_desc" msgid="4502367770068777202">"Přeložit vybraný text"</string> <string name="define" msgid="7394820043869954211">"Definovat"</string> - <string name="define_desc" msgid="7910883642444919726">"Definuje vybraný text"</string> + <string name="define_desc" msgid="7910883642444919726">"Definovat vybraný text"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"V úložišti je málo místa"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Některé systémové funkce nemusí fungovat"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Pro systém není dostatek místa v úložišti. Uvolněte alespoň 250 MB místa a restartujte zařízení."</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet se aktualizuje…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Zařízení se aktualizuje…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon se spouští…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Spouštění systému Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet se spouští…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Zařízení se spouští…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Probíhá optimalizace úložiště."</string> @@ -1283,6 +1288,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Všechny sítě"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Připojeno k síti Wi-Fi navrhované aplikací <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Chcete aplikaci <xliff:g id="NAME">%s</xliff:g> povolit, aby vám navrhovala sítě?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ano"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se zapne automaticky"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Když budete v dosahu kvalitní uložené sítě"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Znovu nezapínat"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 0167acf54c55..2795efeaa55c 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillader, at appen kan få adgang til telefonfunktionerne på enheden. Med denne tilladelse kan appen fastslå telefonnummeret og enheds-id\'erne, hvorvidt et opkald er aktivt samt det eksterne nummer, der oprettes forbindelse til via et opkald."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"dirigere opkald gennem systemet"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Tillader appen at dirigere sine opkald gennem systemet for at forbedre opkaldsoplevelsen."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"se og styre opkald via systemet."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Tillader, at appen kan se og styre igangværende opkald på enheden. Dette omfatter oplysninger såsom telefonnumre og status for opkaldene."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"fortsætte et opkald fra en anden app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Tillader, at appen fortsætter et opkald, der blev startet i en anden app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"læse telefonnumre"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Tillader, at appen kan kommunikere med NFC-tags (Near Field Communication), -kort og -læsere."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivere din skærmlås"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tillader, at appen kan deaktivere tastaturlåsen og anden form for tilknyttet adgangskodesikkerhed. Telefonen deaktiverer f.eks. tastaturlåsen ved indgående telefonopkald og aktiverer tastaturlåsen igen, når opkaldet er afsluttet."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"få og anmode om skærmlåsens kompleksitet"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Giver appen tilladelse til at kende skærmlåsens kompleksitet (høj, medium, lav eller ingen), hvilket indikerer skærmlåsens mulige længde og type. Appen kan også foreslå brugerne at opdatere deres skærmlås til et bestemt niveau, men brugerne kan frit ignorere det og gå videre. Bemærk! Skærmlåsen gemmes ikke som almindelig tekst, så appen kender ikke adgangskoden."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"brug biometrisk hardware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Tillader, at appen kan bruge biometrisk hardware til godkendelse"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"administrer fingeraftrykhardware"</string> @@ -1083,15 +1087,15 @@ <string name="deleteText" msgid="6979668428458199034">"Slet"</string> <string name="inputMethod" msgid="1653630062304567879">"Inputmetode"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string> - <string name="email" msgid="4560673117055050403">"E-mail"</string> + <string name="email" msgid="4560673117055050403">"Send mail"</string> <string name="email_desc" msgid="3638665569546416795">"Send en mail til den valgte adresse"</string> <string name="dial" msgid="1253998302767701559">"Ring op"</string> <string name="dial_desc" msgid="6573723404985517250">"Ring til det valgte telefonnummer"</string> - <string name="map" msgid="5441053548030107189">"Kort"</string> + <string name="map" msgid="5441053548030107189">"Åbn kort"</string> <string name="map_desc" msgid="1836995341943772348">"Find den valgte adresse"</string> <string name="browse" msgid="1245903488306147205">"Åbn"</string> <string name="browse_desc" msgid="8220976549618935044">"Åbn den valgte webadresse"</string> - <string name="sms" msgid="4560537514610063430">"Besked"</string> + <string name="sms" msgid="4560537514610063430">"Send besked"</string> <string name="sms_desc" msgid="7526588350969638809">"Send en besked til det valgte telefonnummer"</string> <string name="add_contact" msgid="7867066569670597203">"Tilføj"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Føj til kontaktpersoner"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Denne tablet opdaterer…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Enheden opdaterer…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefonen starter…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android starter..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Denne tablet starter…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Enheden starter…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Lageret optimeres."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netværk"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Forbundet til Wi‑Fi-netværket, som <xliff:g id="NAME">%s</xliff:g> har foreslået"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Vil du tillade, at <xliff:g id="NAME">%s</xliff:g> foreslår netværk?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi aktiveres automatisk"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Når du er i nærheden af et gemt netværk af høj kvalitet"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Aktivér ikke igen"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index a14a87130ff5..608743874cc6 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -324,7 +324,7 @@ <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Text bei der Eingabe beobachten"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Einschließlich personenbezogener Daten wie Kreditkartennummern und Passwörter."</string> <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Displayvergrößerung festlegen"</string> - <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Legt die Zoom-Stufe des Displays und die Zoom-Position auf dem Display fest."</string> + <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Legt die Zoom-Stufe und -Position auf dem Display fest."</string> <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Bewegungen möglich"</string> <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Tippen, Wischen, Zusammenziehen und andere Bewegungen möglich."</string> <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Bewegungen auf dem Fingerabdrucksensor"</string> @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ermöglicht der App, auf die Telefonfunktionen des Geräts zuzugreifen. Die Berechtigung erlaubt der App, die Telefonnummer und Geräte-IDs zu erfassen, festzustellen, ob gerade ein Gespräch geführt wird, und die Rufnummer verbundener Anrufer zu lesen."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"Anrufe über das System durchführen"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Ermöglicht der App, Anrufe über das System durchzuführen, um die Anrufqualität zu verbessern."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Anrufe durch das System einsehen und verwalten."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Ermöglicht der App, aktuelle Anrufe einzusehen und zu verwalten. Dies beinhaltet Informationen wie Nummern für Anrufe und den Status der Anrufe."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"Anruf aus einer anderen App weiterführen"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Ermöglicht der App, einen Anruf weiterzuführen, der in einer anderen App begonnen wurde."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"Telefonnummern vorlesen"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"Komplexität der Displaysperre erfahren und anfragen"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"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, die Displaysperre auf eine bestimmte Stufe zu aktualisieren, Nutzer können diesen Vorschlag jedoch auch einfach ignorieren und fortfahren. Beachten Sie, dass die Displaysperre nicht im Klartext gespeichert ist, sodass die App nicht das genaue Passwort kennt."</string> <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> @@ -1083,21 +1087,21 @@ <string name="deleteText" msgid="6979668428458199034">"Löschen"</string> <string name="inputMethod" msgid="1653630062304567879">"Eingabemethode"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string> - <string name="email" msgid="4560673117055050403">"E-Mail"</string> + <string name="email" msgid="4560673117055050403">"E-Mail senden"</string> <string name="email_desc" msgid="3638665569546416795">"E-Mail an ausgewählte Adresse senden"</string> <string name="dial" msgid="1253998302767701559">"Anrufen"</string> <string name="dial_desc" msgid="6573723404985517250">"Ausgewählte Telefonnummer anrufen"</string> - <string name="map" msgid="5441053548030107189">"Karte"</string> + <string name="map" msgid="5441053548030107189">"Karte öffnen"</string> <string name="map_desc" msgid="1836995341943772348">"Ausgewählte Adresse finden"</string> <string name="browse" msgid="1245903488306147205">"Öffnen"</string> <string name="browse_desc" msgid="8220976549618935044">"Ausgewählte URL öffnen"</string> - <string name="sms" msgid="4560537514610063430">"SMS"</string> + <string name="sms" msgid="4560537514610063430">"SMS senden"</string> <string name="sms_desc" msgid="7526588350969638809">"SMS an ausgewählte Telefonnummer senden"</string> <string name="add_contact" msgid="7867066569670597203">"Hinzufügen"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Zu Kontakten hinzufügen"</string> - <string name="view_calendar" msgid="979609872939597838">"Anzeigen"</string> + <string name="view_calendar" msgid="979609872939597838">"Aufrufen"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Ausgewählte Zeit im Kalender anzeigen"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Terminübersicht"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Termin planen"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Termin für die ausgewählte Zeit planen"</string> <string name="view_flight" msgid="7691640491425680214">"Verfolgen"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Ausgewählten Flug verfolgen"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet wird aktualisiert…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Gerät wird aktualisiert…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Smartphone wird gestartet…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android wird gestartet…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet wird gestartet…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Gerät wird gestartet…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Speicher wird optimiert"</string> @@ -1239,6 +1244,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="1524719325616630906">"Mit einem von <xliff:g id="NAME">%s</xliff:g> vorgeschlagenen WLAN-Netzwerk verbunden"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Möchten Sie, dass <xliff:g id="NAME">%s</xliff:g> Ihnen Netzwerke vorschlägt?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wenn du in der Nähe eines sicheren gespeicherten Netzwerks bist"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nicht wieder aktivieren"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 3c251e21417b..f89930979a11 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Επιτρέπει στην εφαρμογή την πρόσβαση στις λειτουργίες τηλεφώνου της συσκευής. Αυτή η άδεια δίνει τη δυνατότητα στην εφαρμογή να καθορίζει τον αριθμό τηλεφώνου και τα αναγνωριστικά συσκευών, εάν μια κλήση είναι ενεργή, καθώς και τον απομακρυσμένο αριθμό που συνδέεται από μια κλήση."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"δρομολόγηση κλήσεων μέσω του συστήματος"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Επιτρέπει στην εφαρμογή να δρομολογεί τις κλήσεις της μέσω του συστήματος για να βελτιώσει την εμπειρία κλήσης."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"προβολή και έλεγχος κλήσεων μέσω του συστήματος."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Επιτρέπει στην εφαρμογή να βλέπει και να ελέγχει τις εισερχόμενες κλήσεις στη συσκευή. Αυτό περιλαμβάνει πληροφορίες όπως τους αριθμούς κλήσεων για τις κλήσεις και την κατάσταση των κλήσεων."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"συνέχιση κλήσης από άλλη συσκευή"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Επιτρέπει στην εφαρμογή να συνεχίσει μια κλήση η οποία ξεκίνησε σε άλλη εφαρμογή."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ανάγνωση αριθμών τηλεφώνου"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"λήψη και υποβολή αιτήματος για πολυπλοκότητα οθόνης κλειδώματος"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Επιτρέπει στην εφαρμογή να μάθει το επίπεδο πολυπλοκότητας του κλειδώματος οθόνης (υψηλό, μέσο, χαμηλό ή κανένα), το οποίο υποδεικνύει το πιθανό εύρος του μήκους και του τύπου κλειδώματος οθόνης. Η εφαρμογή μπορεί επίσης να προτείνει στους χρήστες να ενημερώσουν το κλείδωμα οθόνης σε ένα συγκεκριμένο επίπεδο, όμως οι χρήστες μπορούν να την αγνοήσουν και να συνεχίσουν. Λάβετε υπόψη ότι το κλείδωμα οθόνης δεν αποθηκεύεται σε απλό κείμενο. Συνεπώς, η εφαρμογή δεν γνωρίζει τον κωδικό."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"χρήση βιομετρικού εξοπλισμού"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί βιομετρικό εξοπλισμό για έλεγχο ταυτότητας"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"διαχειρίζεται τον εξοπλισμό δακτυλικού αποτυπώματος"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Ενημέρωση tablet…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Ενημέρωση συστήματος…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Εκκίνηση τηλεφώνου…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Εκκίνηση Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Εκκίνηση tablet…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Εκκίνηση συσκευής…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Βελτιστοποίηση αποθηκευτικού χώρου."</string> @@ -1239,6 +1244,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="1524719325616630906">"Σύνδεση στο δίκτυο Wi‑Fi που προτάθηκε από την εφαρμογή <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Θέλετε να επιτρέψετε στην εφαρμογή <xliff:g id="NAME">%s</xliff:g> να σας προτείνει δίκτυα;"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Όταν βρίσκεστε κοντά σε αποθηκευμένο δίκτυο υψηλής ποιότητας"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Να μην ενεργοποιηθεί ξανά"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 4b983c07ed8c..7288a80d01b9 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"route calls through the system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Allows the app to route its calls through the system in order to improve the calling experience."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"see and control calls through the system."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Allows the app to see and control ongoing calls on the device. This includes information such as call numbers for calls and the state of the calls."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continue a call from another app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Allows the app to continue a call which was started in another app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"read phone numbers"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"get and request screen lock complexity"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet is updating…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Device is updating…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Phone is starting…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android is starting…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet is starting…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Device is starting…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Connected to Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Do you want to let <xliff:g id="NAME">%s</xliff:g> propose networks for you?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 821ac1e7a06d..04817558d544 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"route calls through the system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Allows the app to route its calls through the system in order to improve the calling experience."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"see and control calls through the system."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Allows the app to see and control ongoing calls on the device. This includes information such as call numbers for calls and the state of the calls."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continue a call from another app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Allows the app to continue a call which was started in another app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"read phone numbers"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"get and request screen lock complexity"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet is updating…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Device is updating…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Phone is starting…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android is starting…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet is starting…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Device is starting…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Connected to Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Do you want to let <xliff:g id="NAME">%s</xliff:g> propose networks for you?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 4b983c07ed8c..7288a80d01b9 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"route calls through the system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Allows the app to route its calls through the system in order to improve the calling experience."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"see and control calls through the system."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Allows the app to see and control ongoing calls on the device. This includes information such as call numbers for calls and the state of the calls."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continue a call from another app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Allows the app to continue a call which was started in another app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"read phone numbers"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"get and request screen lock complexity"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet is updating…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Device is updating…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Phone is starting…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android is starting…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet is starting…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Device is starting…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Connected to Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Do you want to let <xliff:g id="NAME">%s</xliff:g> propose networks for you?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 4b983c07ed8c..7288a80d01b9 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"route calls through the system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Allows the app to route its calls through the system in order to improve the calling experience."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"see and control calls through the system."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Allows the app to see and control ongoing calls on the device. This includes information such as call numbers for calls and the state of the calls."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continue a call from another app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Allows the app to continue a call which was started in another app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"read phone numbers"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"get and request screen lock complexity"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet is updating…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Device is updating…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Phone is starting…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android is starting…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet is starting…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Device is starting…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Connected to Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Do you want to let <xliff:g id="NAME">%s</xliff:g> propose networks for you?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 3781945bc11c..5d3b466299ff 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active, and the remote number connected by a call."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"route calls through the system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Allows the app to route its calls through the system in order to improve the calling experience."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"see and control calls through the system."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Allows the app to see and control ongoing calls on the device. This includes information such as call numbers for calls and the state of the calls."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continue a call from another app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Allows the app to continue a call which was started in another app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"read phone numbers"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards, and readers."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"get and request screen lock complexity"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plaintext so the app does not know the exact password."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string> @@ -1179,6 +1183,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet is updating…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Device is updating…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Phone is starting…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android is starting…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet is starting…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Device is starting…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizing storage."</string> @@ -1237,6 +1242,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Connected to Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Do you want to let <xliff:g id="NAME">%s</xliff:g> propose networks for you?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 50ebc492b62b..d369da5f1387 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"Transmite llamadas a través del sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permite que la app transmita las llamadas a través del sistema para mejorar la experiencia de llamadas."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Mirar y controlar las llamadas con el sistema"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permite que la app vea y controle las llamadas entrantes del dispositivo. Incluye información como los números emisores y el estado de las llamadas."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuar llamada de otra app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permite que la app continúe con una llamada que se inició en otra app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"leer números de teléfono"</string> @@ -507,6 +509,8 @@ <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">"desactivar el bloqueo de pantalla"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que la aplicación desactive el bloqueo del teclado y cualquier protección con contraseña asociada. Por ejemplo, el dispositivo puede desactivar el bloqueo del teclado cuando recibe una llamada telefónica y volver a activarlo cuando finaliza la llamada."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"obtener y solicitar complejidad del bloqueo de pantalla"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Permite que la app conozca el nivel de complejidad del bloqueo de pantalla (alta, media, baja o ninguna), lo que indica el rango de duración posible y el tipo de bloqueo de pantalla. La app también puede sugerirles a los usuarios que actualicen el bloqueo de pantalla a un determinado nivel, aunque ellos pueden ignorar esta sugerencia y seguir navegando. Ten en cuenta que el bloqueo de pantalla no se almacena como texto sin formato, por lo que la app no conoce la contraseña exacta."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"usar hardware biométrico"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que la app use hardware biométrico para realizar la autenticación"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Administrar el hardware de huellas digitales"</string> @@ -1088,7 +1092,7 @@ <string name="dial" msgid="1253998302767701559">"Llamar"</string> <string name="dial_desc" msgid="6573723404985517250">"Llamar al número de teléfono seleccionado"</string> <string name="map" msgid="5441053548030107189">"Mapa"</string> - <string name="map_desc" msgid="1836995341943772348">"Abrir la dirección seleccionada en el mapa"</string> + <string name="map_desc" msgid="1836995341943772348">"Buscar la dirección seleccionada"</string> <string name="browse" msgid="1245903488306147205">"Abrir"</string> <string name="browse_desc" msgid="8220976549618935044">"Abrir URL seleccionada"</string> <string name="sms" msgid="4560537514610063430">"Mensaje"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Actualizando tablet…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Actualizando dispositivo…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Iniciando teléfono…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Iniciando Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Iniciando tablet…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Iniciando dispositivo…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamiento"</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas las redes"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Se estableció conexión con la red Wi-Fi sugerida por <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"¿Quieres permitir que <xliff:g id="NAME">%s</xliff:g> te sugiera redes?"</string> + <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">"Se activará la conexión Wi-Fi automáticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cuando estés cerca de una red guardada de alta calidad"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No volver a activar"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 7a992b489aa0..91742482bc1d 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"direccionar llamadas a través del sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permite a la aplicación direccionar sus llamadas hacia el sistema para mejorar la calidad de estas."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ver y controlar llamadas a través del sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permite que la aplicación vea y controle las llamadas entrantes en el dispositivo. Esto incluye información como los números de las llamadas y su estado."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuar una llamada de otra aplicación"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permite que la aplicación continúe una llamada que se ha iniciado en otra aplicación."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"leer números de teléfono"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"obtener y solicitar el nivel de complejidad del bloqueo de pantalla"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"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> <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> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"Eliminar"</string> <string name="inputMethod" msgid="1653630062304567879">"Método de introducción de texto"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string> - <string name="email" msgid="4560673117055050403">"Correo electrónico"</string> + <string name="email" msgid="4560673117055050403">"Enviar correo"</string> <string name="email_desc" msgid="3638665569546416795">"Enviar un correo electrónico a la dirección seleccionada"</string> <string name="dial" msgid="1253998302767701559">"Llamar"</string> <string name="dial_desc" msgid="6573723404985517250">"Llamar al número de teléfono seleccionado"</string> @@ -1091,15 +1095,15 @@ <string name="map_desc" msgid="1836995341943772348">"Buscar la dirección seleccionada"</string> <string name="browse" msgid="1245903488306147205">"Abrir"</string> <string name="browse_desc" msgid="8220976549618935044">"Abrir la URL seleccionada"</string> - <string name="sms" msgid="4560537514610063430">"Mensaje"</string> - <string name="sms_desc" msgid="7526588350969638809">"Enviar un mensaje al número de teléfono seleccionado"</string> + <string name="sms" msgid="4560537514610063430">"Enviar SMS"</string> + <string name="sms_desc" msgid="7526588350969638809">"Enviar SMS al teléfono seleccionado"</string> <string name="add_contact" msgid="7867066569670597203">"Añadir"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Añadir a contactos"</string> <string name="view_calendar" msgid="979609872939597838">"Ver"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Ver la hora seleccionada en el calendario"</string> <string name="add_calendar_event" msgid="1953664627192056206">"Programar"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Programar un evento para la hora seleccionada"</string> - <string name="view_flight" msgid="7691640491425680214">"Buscar"</string> + <string name="view_flight" msgid="7691640491425680214">"Hacer seguimiento"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Seguir el vuelo seleccionado"</string> <string name="translate" msgid="9218619809342576858">"Traducir"</string> <string name="translate_desc" msgid="4502367770068777202">"Traducir el texto seleccionado"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"El tablet se está actualizando…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"El dispositivo se está actualizando…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"El teléfono se está iniciando…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android se está iniciando…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"El tablet se está iniciando…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"El dispositivo se está iniciando…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamiento."</string> @@ -1239,6 +1244,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="1524719325616630906">"Conexión establecida con la red Wi‑Fi recomendada por <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"¿Quieres que <xliff:g id="NAME">%s</xliff:g> te recomiende redes?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cuando estés cerca de una red de alta calidad guardada"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No volver a activar"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index e633ab46bf25..f20b35ff15c9 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Annab rakendusele juurdepääsu seadme telefonifunktsioonidele. See luba võimaldab rakendusel määrata telefoninumbri ja seadme ID-d ning kontrollida, kas kõne on aktiivne ja kaugnumber on kõne kaudu telefoniga ühendatud."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"kõnede marsruutimine süsteemi kaudu"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Võimaldab rakendusel kõnesid süsteemi kaudu marsruutida, et helistamiskogemust täiustada."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"süsteemi kaudu kõnede vaatamine ja juhtimine."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Lubab rakendusel seadmes vaadata ja juhtida käimasolevaid kõnesid. See hõlmab sellist teavet nagu kõnede numbrid ja olek."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"jätka kõnet teises rakenduses"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Lubab rakendusel jätkata kõnet, mida alustati teises rakenduses."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lugeda telefoninumbreid"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Võimaldab rakendusel suhelda lähiväljaside (NFC) märgendite, kaartide ja lugeritega."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"keelake ekraanilukk"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Võimaldab rakendusel keelata klahviluku ja muu seotud parooli turvalisuse. Näiteks keelab telefon klahviluku sissetuleva kõne vastuvõtmisel ja lubab klahviluku uuesti, kui kõne on lõpetatud."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"Hankida ja taotleda ekraaniluku keerukuse teavet"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Lubab rakendusel vaadata ekraaniluku keerukuse taset (kõrge, keskmine, madal või puudub), mis näitab ekraaniluku võimalikku pikkust ja tüüpi. Rakendus võib kasutajatele soovitada ka ekraaniluku viimist teatud tasemele, kuid kasutajad võivad seda eirata ja kuvalt lahkuda. Pange tähele, et ekraanilukku ei salvestata lihttekstina, seega ei tea rakendus täpset parooli."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"kasutada biomeetrilist riistvara"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Võimaldab rakendusel autentimiseks kasutada biomeetrilist riistvara"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"sõrmejälje riistvara haldamine"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tahvelarvutit värskendatakse …"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Seadet värskendatakse …"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon käivitub …"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android käivitub ..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tahvelarvuti käivitub …"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Seade käivitub …"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Salvestusruumi optimeerimine."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kõik võrgud"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Ühendatud rakenduse <xliff:g id="NAME">%s</xliff:g> soovitatud WiFi-võrguga"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Kas soovite lubada rakendusel <xliff:g id="NAME">%s</xliff:g> teile võrke soovitada?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jah"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WiFi lülitub sisse automaatselt"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kui olete kvaliteetse salvestatud võrgu läheduses"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ära lülita tagasi sisse"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index ea9414ff9bd3..153eeae57584 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Gailuaren telefono-eginbideak atzitzeko baimena ematen die aplikazioei. Baimen horrek aplikazioari telefono-zenbakia eta gailu IDak zein diren, deirik aktibo dagoen eta deia zer zenbakirekin konektatuta dagoen zehazteko baimena ematen die aplikazioei."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"bideratu deiak sistemaren bidez"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Deiak sistemaren bidez bideratzea baimentzen die aplikazioei, deien zerbitzua ahal bezain ona izan dadin."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ikusi eta kontrolatu deiak sistemaren bidez."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Gailuan abian diren deiak eta deion informazioa ikusi eta kontrolatzeko baimena ematen dio aplikazioari; besteak beste, deien zenbakiak eta deien egoera."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"Jarraitu beste aplikazio batean hasitako deia"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Beste aplikazio batean hasitako dei bat jarraitzea baimentzen dio aplikazioari."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"irakurri telefono-zenbakiak"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"lortu eta eskatu pantailaren blokeoaren konplexutasuna"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Pantailaren blokeoaren konplexutasun-maila (handia, ertaina, txikia edo bat ere ez) ezagutzea baimentzen dio aplikazioari; horren 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 pasahitza zehazki zein den."</string> <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> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"Ezabatu"</string> <string name="inputMethod" msgid="1653630062304567879">"Idazketa-metodoa"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Testu-ekintzak"</string> - <string name="email" msgid="4560673117055050403">"Posta"</string> + <string name="email" msgid="4560673117055050403">"Bidali mezu bat"</string> <string name="email_desc" msgid="3638665569546416795">"Bidali mezu elektroniko bat hautatutako helbidera"</string> <string name="dial" msgid="1253998302767701559">"Deitu"</string> <string name="dial_desc" msgid="6573723404985517250">"Deitu hautatutako telefono-zenbakira"</string> @@ -1091,7 +1095,7 @@ <string name="map_desc" msgid="1836995341943772348">"Bilatu hautatutako helbidea"</string> <string name="browse" msgid="1245903488306147205">"Ireki"</string> <string name="browse_desc" msgid="8220976549618935044">"Ireki hautatutako URLa"</string> - <string name="sms" msgid="4560537514610063430">"Bidali mezua"</string> + <string name="sms" msgid="4560537514610063430">"Bidali SMS bat"</string> <string name="sms_desc" msgid="7526588350969638809">"Bidali testu-mezu bat hautatutako telefono-zenbakira"</string> <string name="add_contact" msgid="7867066569670597203">"Gehitu"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Gehitu kontaktuetan"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tableta eguneratzen ari da…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Gailua eguneratzen ari da…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefonoa abiarazten ari da…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android abiarazten ari da…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tableta abiarazten ari da…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Gailua abiarazten ari da…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Memoria optimizatzen."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> aplikazioak iradokitako Wi‑Fi sarera konektatuta"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> aplikazioak sareak iradoki diezazkizun nahi duzu?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gordeta daukazun kalitate handiko sare batetik gertu zaudenean"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ez aktibatu berriro"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 1099169d55b5..76845c8d9714 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"به برنامه اجازه میدهد به ویژگیهای تلفن دستگاه شما دسترسی پیدا کند. این مجوز به برنامه اجازه میدهد شماره تلفن و شناسههای دستگاه، فعال بودن یک تماس و شماره راه دوری که با یک تماس متصل شده است را مشخص کند."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"برقرار کردن تماسها ازطریق سیستم"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"به برنامه امکان میدهد برای بهبود تجربه تماس، تماسهایش را ازطریق سیستم برقرار کند."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"دیدن و کنترل تماسها ازطریق سیستم."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"به برنامهها اجازه میدهد تماسهای درحال انجام را در این دستگاه ببیند و کنترل کند. این مورد شامل اطلاعاتی مانند شماره تلفن برای تماسها و وضعیت تماسها است."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ادامه دادن تماس از برنامهای دیگر"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"به برنامه اجازه میدهد تماسی را که در برنامه دیگری شروع شده ادامه دهد."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"خواندن شماره تلفنها"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"دریافت و درخواست پیچیدگی قفل صفحه"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"به برنامه اجازه میدهد سطح پیچیدگی قفل صفحه (بالا، متوسط، پایین یا هیچکدام) را بیاموزد که نشانگر اشکال مختلف طول و نوع قفل صفحه است. همچنین برنامه میتواند به کاربران پیشنهاد دهد قفل صفحه را به سطح خاصی بهروزرسانی کنند، اما کاربران میتوانند آزادانه این پیشنهاد را نادیده بگیرند و به سطح دیگری بروند. توجه داشته باشید که قفل صفحه در قالب نوشتار ساده ذخیره نمیشود، بنابراین برنامه گذرواژه دقیق را نمیداند."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"استفاده از سختافزار بیومتریک"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"به برنامه امکان میدهد از سختافزار بیومتریک برای احراز هویت استفاده کند"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"مدیریت سختافزار اثر انگشت"</string> @@ -1083,27 +1087,27 @@ <string name="deleteText" msgid="6979668428458199034">"حذف"</string> <string name="inputMethod" msgid="1653630062304567879">"روش ورودی"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"کنشهای متنی"</string> - <string name="email" msgid="4560673117055050403">"ایمیل"</string> + <string name="email" msgid="4560673117055050403">"فرستادن ایمیل"</string> <string name="email_desc" msgid="3638665569546416795">"ارسال ایمیل به نشانی انتخابی"</string> - <string name="dial" msgid="1253998302767701559">"تماس"</string> + <string name="dial" msgid="1253998302767701559">"تماس گرفتن"</string> <string name="dial_desc" msgid="6573723404985517250">"تماس با شماره تلفن انتخابی"</string> <string name="map" msgid="5441053548030107189">"نقشه"</string> <string name="map_desc" msgid="1836995341943772348">"مکانیابی نشانی انتخابشده"</string> <string name="browse" msgid="1245903488306147205">"باز کردن"</string> <string name="browse_desc" msgid="8220976549618935044">"باز کردن نشانی وب انتخابی"</string> - <string name="sms" msgid="4560537514610063430">"پیام"</string> + <string name="sms" msgid="4560537514610063430">"فرستادن پیام"</string> <string name="sms_desc" msgid="7526588350969638809">"ارسال پیام به شماره تلفن انتخابی"</string> <string name="add_contact" msgid="7867066569670597203">"افزودن"</string> <string name="add_contact_desc" msgid="4830217847004590345">"افزودن به مخاطبین"</string> <string name="view_calendar" msgid="979609872939597838">"مشاهده"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"مشاهده زمان انتخابی در تقویم"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"زمانبندی"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"زمانبندی کردن"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"زمانبندی رویداد برای زمان انتخابی"</string> - <string name="view_flight" msgid="7691640491425680214">"پیگیری"</string> + <string name="view_flight" msgid="7691640491425680214">"انجام پیگیری"</string> <string name="view_flight_desc" msgid="3876322502674253506">"ردیابی پرواز انتخابی"</string> <string name="translate" msgid="9218619809342576858">"ترجمه کردن"</string> <string name="translate_desc" msgid="4502367770068777202">"ترجمه کردن نوشتار انتخابشده"</string> - <string name="define" msgid="7394820043869954211">"تعریف"</string> + <string name="define" msgid="7394820043869954211">"تعریف کردن"</string> <string name="define_desc" msgid="7910883642444919726">"تعریف نوشتار انتخابی"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"حافظه درحال پر شدن است"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"رایانه لوحی درحال بهروزرسانی است…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"دستگاه درحال بهروزرسانی است…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"تلفن درحال راهاندازی است…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android در حال راهاندازی است..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"رایانه لوحی درحال راهاندازی است…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"دستگاه درحال راهاندازی است…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"بهینهسازی فضای ذخیرهسازی."</string> @@ -1239,6 +1244,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="1524719325616630906">"متصل به شبکه Wi‑Fi پیشنهادی <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"میخواهید به <xliff:g id="NAME">%s</xliff:g> اجازه دهید شبکههایی را که به شما پیشنهاد کند؟"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"وقتی نزدیک شبکه ذخیرهشده با کیفیت بالا هستید"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"دوباره روشن نشود"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 3f8f0d126032..16c96ccba166 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Antaa sovelluksen käyttää laitteen puhelinominaisuuksia. Sovellus voi määrittää puhelinnumeron ja laitteen tunnuksen, puhelun tilan sekä soitetun numeron."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ohjata puhelut järjestelmän kautta"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Tämä sallii sovelluksen ohjata puhelut järjestelmän kautta, mikä auttaa parantamaan puhelujen laatua."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"nähdä puhelut ja päättää niistä järjestelmässä"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Sovellus voi nähdä laitteella käynnissä olevat puhelut ja päättää niistä. Se näkee esimerkiksi puheluihin liittyvät numerot ja niiden tilat."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"jatkaa toisen sovelluksen puhelua"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Antaa sovelluksen jatkaa puhelua, joka aloitettiin toisessa sovelluksessa."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lukea puhelinnumeroita"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Antaa sovelluksen kommunikoida NFC (Near Field Communication) -tagien, -korttien ja -lukijoiden kanssa."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"poista näytön lukitus käytöstä"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Antaa sovelluksen ottaa näppäinlukon ja siihen liittyvän salasanasuojauksen pois käytöstä. Esimerkki: puhelin poistaa näppäinlukon käytöstä puhelun saapuessa ja asettaa lukon takaisin käyttöön puhelun päättyessä."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"pyytää näytön lukituksen monimutkaisuutta ja nähdä sen"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Sovellus saa luvan selvittää näytön lukituksen monimutkaisuuden (korkea, keskitaso tai matala) eli sen pituusluokan ja tyypin. Sovellus voi myös ehdottaa käyttäjille näytön lukituksen vaihtamista tietylle tasolle, mutta he voivat ohittaa tämän ja poistua. Itse näytön lukitusta ei säilytetä tekstimuodossa, joten sovellus ei tiedä sitä tarkalleen."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"käytä biometristä laitteistoa"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Sallii sovelluksen käyttää biometristä laitteistoa todennukseen"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"sormenjälkilaitteiston hallinnointi"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablettia päivitetään…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Laitetta päivitetään…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Puhelin käynnistyy…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android käynnistyy…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tabletti käynnistyy…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Laite käynnistyy…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimoidaan tallennustilaa."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kaikki verkot"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Yhdistetty ehdotettuun (<xliff:g id="NAME">%s</xliff:g>) Wi-Fi-verkkoon"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Haluatko, että <xliff:g id="NAME">%s</xliff:g> voi ehdottaa sinulle verkkoja?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Kyllä"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi käynnistyy automaattisesti"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kun olet lähellä laadukasta tallennettua verkkoa"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Älä käynnistä uudelleen"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 2bac413a4820..6fb1f1291d9b 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"acheminer les appels dans le système"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permet à l\'application d\'acheminer ses appels dans le système afin d\'améliorer l\'expérience d\'appel."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"afficher et gérer les appels à l\'aide du système."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Autorise l\'application à afficher et à gérer les appels sortants sur l\'appareil. Cela comprend de l\'information comme les numéros pour les appels et l\'état des appels."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuer un appel d\'une autre application"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permet à l\'application de continuer un appel commencé dans une autre application."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lire les numéros de téléphone"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"obtenir et demander la complexité de l\'écran de verrouillage"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"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> <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> @@ -1083,24 +1087,24 @@ <string name="deleteText" msgid="6979668428458199034">"Supprimer"</string> <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string> - <string name="email" msgid="4560673117055050403">"Courriel"</string> + <string name="email" msgid="4560673117055050403">"Envoyer un courriel"</string> <string name="email_desc" msgid="3638665569546416795">"Envoyer un courriel à l\'adresse sélectionnée"</string> - <string name="dial" msgid="1253998302767701559">"Appel"</string> + <string name="dial" msgid="1253998302767701559">"Appeler"</string> <string name="dial_desc" msgid="6573723404985517250">"Téléphoner au numéro sélectionné"</string> - <string name="map" msgid="5441053548030107189">"Carte"</string> + <string name="map" msgid="5441053548030107189">"Ouvrir une carte"</string> <string name="map_desc" msgid="1836995341943772348">"Localiser l\'adresse sélectionnée"</string> <string name="browse" msgid="1245903488306147205">"Ouvrir"</string> <string name="browse_desc" msgid="8220976549618935044">"Ouvrir l\'adresse URL sélectionnée"</string> - <string name="sms" msgid="4560537514610063430">"Message"</string> + <string name="sms" msgid="4560537514610063430">"Envoyer un texto"</string> <string name="sms_desc" msgid="7526588350969638809">"Envoyer un message texte au numéro de téléphone sélectionné"</string> <string name="add_contact" msgid="7867066569670597203">"Ajouter"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Ajouter aux contacts"</string> <string name="view_calendar" msgid="979609872939597838">"Afficher"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Voir la date sélectionnée dans l\'agenda"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Calendrier"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"Planifier un événement pour l\'heure sélectionnée"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Planifier"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"Planifier un événement à l\'heure sélectionnée"</string> <string name="view_flight" msgid="7691640491425680214">"Effectuer le suivi"</string> - <string name="view_flight_desc" msgid="3876322502674253506">"Faire le suivi du vol sélectionné"</string> + <string name="view_flight_desc" msgid="3876322502674253506">"Obtenir des informations sur le vol sélectionné"</string> <string name="translate" msgid="9218619809342576858">"Traduire"</string> <string name="translate_desc" msgid="4502367770068777202">"Traduire le texte sélectionné"</string> <string name="define" msgid="7394820043869954211">"Définir"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Mise à jour de la tablette en cours…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Mise à jour de l\'appareil en cours…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Démarrage du téléphone en cours…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android en cours de démarrage..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Démarrage de la tablette en cours…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Démarrage de l\'appareil en cours…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimisation du stockage."</string> @@ -1239,6 +1244,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="1524719325616630906">"Connecté au réseau Wi-Fi proposé par <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Voulez-vous autoriser <xliff:g id="NAME">%s</xliff:g> à vous suggérer des réseaux?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Lorsque vous êtes près d\'un réseau enregistré de haute qualité"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne pas réactiver"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index c0c2ed8216db..fa8c7f0de1a1 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"acheminer les appels via le système"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Autorise l\'application à acheminer les appels via le système afin d\'optimiser le confort d\'utilisation."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"voir et contrôler les appels via le système."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permet à l\'application de voir et contrôler les appels en cours sur l\'appareil. Cela inclut des informations telles que les numéros associés aux appels et l\'état des appels."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuer un appel issu d\'une autre application"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Autorise l\'application à continuer un appel qui a été démarré dans une autre application."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lire les numéros de téléphone"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"obtenir et demander la complexité du verrouillage de l\'écran"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"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> <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> @@ -1083,16 +1087,16 @@ <string name="deleteText" msgid="6979668428458199034">"Supprimer"</string> <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string> - <string name="email" msgid="4560673117055050403">"E-mail"</string> + <string name="email" msgid="4560673117055050403">"Envoyer un e-mail"</string> <string name="email_desc" msgid="3638665569546416795">"Envoyer un e-mail à l\'adresse sélectionnée"</string> <string name="dial" msgid="1253998302767701559">"Appeler"</string> <string name="dial_desc" msgid="6573723404985517250">"Appeler le numéro de téléphone sélectionné"</string> - <string name="map" msgid="5441053548030107189">"Carte"</string> + <string name="map" msgid="5441053548030107189">"Ouvrir une carte"</string> <string name="map_desc" msgid="1836995341943772348">"Localiser l\'adresse sélectionnée"</string> <string name="browse" msgid="1245903488306147205">"Ouvrir"</string> <string name="browse_desc" msgid="8220976549618935044">"Ouvrir l\'URL sélectionnée"</string> - <string name="sms" msgid="4560537514610063430">"Envoyer un message"</string> - <string name="sms_desc" msgid="7526588350969638809">"Envoyer un message au numéro de téléphone sélectionné"</string> + <string name="sms" msgid="4560537514610063430">"Envoyer un SMS"</string> + <string name="sms_desc" msgid="7526588350969638809">"Envoyer un SMS au numéro de téléphone sélectionné"</string> <string name="add_contact" msgid="7867066569670597203">"Ajouter"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Ajouter aux contacts"</string> <string name="view_calendar" msgid="979609872939597838">"Afficher"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Mise à jour de la tablette…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Mise à jour de l\'appareil…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Démarrage du téléphone…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Démarrage d\'Android en cours"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Démarrage de la tablette…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Démarrage de l\'appareil…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimisation du stockage en cours…"</string> @@ -1239,6 +1244,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="1524719325616630906">"Connecté au réseau Wi‑Fi proposé par <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Voulez-vous autoriser <xliff:g id="NAME">%s</xliff:g> à vous proposer des réseaux ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Lorsque vous êtes à proximité d\'un réseau enregistré de haute qualité"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne pas réactiver"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index c5a406608ca8..2c9b09d84668 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite á aplicación acceder ás funcións de teléfono do dispositivo. Con este permiso a aplicación pode determinar o número de teléfono e os ID do dispositivo, se unha chamada está activa e o número remoto conectado mediante unha chamada."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"dirixir as chamadas a través do sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permite á aplicación dirixir as súas chamadas a través do sistema para mellorar a túa experiencia durante as chamadas."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"consultar e controlar as chamadas a través do sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permite que a aplicación consulte e controle as chamadas en curso do dispositivo. Pode acceder a información como os números e os estados das chamadas."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuar unha chamada iniciada noutra aplicación"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permite que a aplicación continúe unha chamada que se iniciou noutra aplicación."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ler números de teléfono"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permite á aplicación comunicarse con etiquetas, tarxetas e lectores Near Field Communication (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivar o bloqueo da pantalla"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguranza dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"consultar complexidade do bloqueo de pantalla e suxerir aumentala"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Permite que a aplicación consulte o nivel (alto, medio, baixo ou inexistente) de complexidade do bloqueo de pantalla para saber a lonxitude aproximada do contrasinal e o tipo de bloqueo de pantalla. A aplicación tamén pode suxerirlles aos usuarios que aumenten o nivel de complexidade do bloqueo de pantalla, aínda que poden ignorar a suxestión e seguir navegando. Ten en conta que o bloqueo de pantalla non se almacena como texto sen formato, polo que a aplicación non pode consultar o contrasinal exacto."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"utilizar hardware biométrico"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que a aplicación utilice hardware biométrico para a autenticación"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"xestionar hardware de impresión dixital"</string> @@ -1091,7 +1095,7 @@ <string name="map_desc" msgid="1836995341943772348">"Localiza o enderezo seleccionado"</string> <string name="browse" msgid="1245903488306147205">"Abrir"</string> <string name="browse_desc" msgid="8220976549618935044">"Abre o URL seleccionado"</string> - <string name="sms" msgid="4560537514610063430">"Mensaxe"</string> + <string name="sms" msgid="4560537514610063430">"Enviar SMS"</string> <string name="sms_desc" msgid="7526588350969638809">"Envía unha mensaxe ao número de teléfono seleccionado"</string> <string name="add_contact" msgid="7867066569670597203">"Engadir"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Engade o elemento aos contactos"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"A tableta estase actualizando…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"O dispositivo estase actualizando…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"O teléfono estase iniciando…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Estase iniciando Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"A tableta estase iniciando…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"O dispositivo estase iniciando…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamento."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Conectácheste á rede wifi proposta pola aplicación <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Queres permitir que a aplicación <xliff:g id="NAME">%s</xliff:g> che propoña redes?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Si"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A wifi activarase automaticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cando esteas preto dunha rede gardada de alta calidade"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Non volver activar"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 4908ed20477d..da8a6e510ed8 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -322,7 +322,7 @@ <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"સ્પર્શ કરીને શોધખોળ કરવું ચાલુ કરો"</string> <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"ટૅપ કરેલ આઇટમ મોટેથી બોલવામાં આવશે અને હાવભાવની મદદથી સ્ક્રીનને શોધી શકાય છે."</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"તમે લખો તે ટેક્સ્ટનું અવલોકન કરો"</string> - <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ક્રેડિટ કાર્ડ નંબર્સ અને પાસવર્ડ્સ જેવો વ્યક્તિગત ડેટા શામેલ છે."</string> + <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ક્રેડિટ કાર્ડ નંબર અને પાસવર્ડ જેવો વ્યક્તિગત ડેટા શામેલ છે."</string> <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"પ્રદર્શન વિસ્તૃતિકરણ નિયંત્રિત કરો"</string> <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"પ્રદર્શનનું ઝૂમ સ્તર અને સ્થિતિનિર્ધારણ નિયંત્રિત કરો."</string> <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"હાવભાવ કરો"</string> @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"એપ્લિકેશનને ફોન સુવિધાઓને ઍક્સેસ કરવાની મંજૂરી આપે છે. આ પરવાનગી એપ્લિકેશનને ફોન નંબર અને ઉપકરણ ID, કૉલ સક્રિય છે અને કોઈ કૉલ દ્વારા કનેક્ટ થયેલ રિમોટ નંબર નિર્ધારિત કરવાની મંજૂરી આપે છે."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"સિસ્ટમ મારફતે કૉલ બીજે વાળો"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"કૉલિંગ અનુભવ સુધારવા માટે ઍપ્લિકેશનને સિસ્ટમ મારફતે કૉલ બીજે વાળવાની મંજૂરી આપે છે."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"સિસ્ટમ મારફતે કૉલ જુઓ અને નિયંત્રિત કરો."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ઍપને ડિવાઇસ પરના ચાલી રહેલા કૉલને જોવાની અને નિયંત્રિત કરવાની મંજૂરી આપે છે. આમાં કૉલ માટેના કૉલ નંબર અને તેની સ્થિતિ જેવી માહિતી શામેલ હોય છે."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"તૃતીય પક્ષ ઍપમાંનો કૉલ ચાલુ રાખો"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"એક અન્ય તૃતીય પક્ષ ઍપમાં ચાલુ થયેલા કૉલને આ ઍપમાં ચાલુ રાખવાની મંજૂરી આપે છે."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ફોન નંબર વાંચો"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"સ્ક્રીન લૉકની જટિલતા મેળવીને વિનંતી કરો"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ઍપને સ્ક્રીન લૉકની જટિલતાનું લેવલ (ઊંચું, મધ્યમ, નીચું અથવા કોઈ નહીં) જાણવાની મંજૂરી આપે છે, જે સ્ક્રીન લૉકના પ્રકાર અને લંબાઈની સંભવિત શ્રેણી સૂચવે છે. ઍપ વપરાશકર્તાઓને સ્ક્રીન લૉકને ચોક્કસ લેવલ સુધી અપડેટ કરવાનું સૂચન પણ કરી શકે છે, પરંતુ વપરાશકર્તાઓ મુક્ત રીતે અવગણીને નૅવિગેટ કરી શકે છે. નોંધી લો કે સ્ક્રીન લૉકનો plaintextમાં સંગ્રહ કરવામાં આવતો નથી, તેથી ઍપને ચોક્કસ પાસવર્ડની જાણ હોતી નથી."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ફિંગરપ્રિન્ટ હાર્ડવેરને સંચાલિત કરો"</string> @@ -1083,11 +1087,11 @@ <string name="deleteText" msgid="6979668428458199034">"ડિલીટ કરો"</string> <string name="inputMethod" msgid="1653630062304567879">"ઇનપુટ પદ્ધતિ"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"ટેક્સ્ટ ક્રિયાઓ"</string> - <string name="email" msgid="4560673117055050403">"ઇમેઇલ"</string> + <string name="email" msgid="4560673117055050403">"ઇમેઇલ કરો"</string> <string name="email_desc" msgid="3638665569546416795">"પસંદ કરેલ ઍડ્રેસ પર ઇમેઇલ મોકલો"</string> <string name="dial" msgid="1253998302767701559">"કૉલ કરો"</string> <string name="dial_desc" msgid="6573723404985517250">"પસંદ કરેલ ફોન નંબર પર કૉલ કરો"</string> - <string name="map" msgid="5441053548030107189">"નકશો"</string> + <string name="map" msgid="5441053548030107189">"નકશો ખોલો"</string> <string name="map_desc" msgid="1836995341943772348">"પસંદ કરેલ સરનામું શોધો"</string> <string name="browse" msgid="1245903488306147205">"ખોલો"</string> <string name="browse_desc" msgid="8220976549618935044">"પસંદ કરેલ URL ખોલો"</string> @@ -1096,7 +1100,7 @@ <string name="add_contact" msgid="7867066569670597203">"ઉમેરો"</string> <string name="add_contact_desc" msgid="4830217847004590345">"સંપર્કોમાં ઉમેરો"</string> <string name="view_calendar" msgid="979609872939597838">"જુઓ"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"કૅલેન્ડરમાં પસંદ કરેલ સમય જુઓ"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"કૅલેન્ડરમાં પસંદ કરેલો સમય જુઓ"</string> <string name="add_calendar_event" msgid="1953664627192056206">"શેડ્યૂલ કરો"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"પસંદ કરેલ સમય માટે ઇવેન્ટ શેડ્યૂલ કરો"</string> <string name="view_flight" msgid="7691640491425680214">"ટ્રૅક કરો"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ટૅબ્લેટ અપડેટ થઈ રહ્યું છે…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ઉપકરણ અપડેટ થઈ રહ્યું છે…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ફોન શરૂ થઈ રહ્યો છે…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android પ્રારંભ થઈ રહ્યું છે…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ટૅબ્લેટ શરૂ થઈ રહ્યું છે…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ઉપકરણ શરૂ થઈ રહ્યું છે…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"સંગ્રહ ઓપ્ટિમાઇઝ કરી રહ્યું છે."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> દ્વારા પ્રસ્તાવિત વાઇ-ફાઇ નેટવર્ક સાથે કનેક્ટ કર્યું"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"શું તમે <xliff:g id="NAME">%s</xliff:g>ને તમારા માટે નેટવર્કનો પ્રસ્તાવ આપવા દેવા માગો છો?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"જ્યારે તમે એક ઉચ્ચ ક્વૉલિટીવાળા સાચવેલ નેટવર્કની નજીક હોવ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"પાછું ચાલુ કરશો નહીં"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 87e1f9785591..4349c09dd516 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ऐप्स को डिवाइस की फ़ोन सुविधाओं तक पहुंचने देता है. यह अनुमति ऐप्स को फ़ोन नंबर और डिवाइस आईडी, कॉल सक्रिय है या नहीं, और कॉल द्वारा कनेक्ट किया गया दूरस्थ नंबर निर्धारित करने देती है."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"सिस्टम के माध्यम से कॉल रूट करें"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करने के अनुभव को बेहतर बनाने के लिए ऐप्लिकेशन को सिस्टम के माध्यम से उसके कॉल रूट करने देती है."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"सिस्टम के ज़रिए कॉल देखना और नियंत्रित करना."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ऐप्लिकेशन को डिवाइस पर चल रहे कॉल देखने और नियंत्रित करने देती है. इसमें कॉल के नंबर और उनकी स्थिति से जुड़ी जानकारी शामिल है."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"दूसरे ऐप्लिकेशन से शुरू किया गया कॉल जारी रखें"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"इसके ज़रिए आप, किसी ऐप्लिकेशन में शुरू किया गया कॉल दूसरे ऐप्लिकेशन में जारी रख सकते हैं."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फ़ोन नंबर पढ़ना"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"स्क्रीन लॉक की कठिनाई का अनुरोध करना और उसे जानना"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ऐप्लिकेशन को स्क्रीन लॉक की कठिनाई का लेवल (बहुत ज़्यादा, मध्यम, कम या बिल्कुल नहीं) जानने देती है, जो स्क्रीन लॉक की लंबाई और उसके प्रकार की उस सीमा के बारे में संकेत देता है, जो शायद हो सकती है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय लेवल तक अपडेट करें. लेकिन उपयोगकर्ता इसे बेझिझक अनदेखा करके छोड़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को सटीक पासवर्ड पता नहीं होता है."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"बायोमीट्रिक हार्डवेयर इस्तेमाल करने दें"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"पुष्टि के लिए, ऐप्लिकेशन को बायोमीट्रिक हार्डवेयर इस्तेमाल करने की मंज़ूरी दें"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"उंगली की छाप के लिए हार्डवेयर को प्रबंधित करें"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"टैबलेट अपडेट हो रहा है…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"डिवाइस अपडेट हो रहा है…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"फ़ोन चालू हो रहा है…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android प्रारंभ हो रहा है…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"टैबलेट चालू हो रहा है…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"डिवाइस चालू हो रहा है…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"मेमोरी ऑप्टिमाइज़ हो रही है."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> के दिए हुए वाई-फ़ाई नेटवर्क से कनेक्ट है"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"क्या आप <xliff:g id="NAME">%s</xliff:g> को आपके लिए नेटवर्क ऑफ़र करने देना चाहते हैं?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"जब आप किसी अच्छी क्वालिटी वाले सेव किए गए नेटवर्क के पास हों"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"वापस चालू न करें"</string> @@ -1407,7 +1416,7 @@ <string name="ime_action_go" msgid="8320845651737369027">"जाएं"</string> <string name="ime_action_search" msgid="658110271822807811">"खोजें"</string> <string name="ime_action_send" msgid="2316166556349314424">"भेजें"</string> - <string name="ime_action_next" msgid="3138843904009813834">"आगे"</string> + <string name="ime_action_next" msgid="3138843904009813834">"आगे बढ़ें"</string> <string name="ime_action_done" msgid="8971516117910934605">"हो गया"</string> <string name="ime_action_previous" msgid="1443550039250105948">"पीछे जाएं"</string> <string name="ime_action_default" msgid="2840921885558045721">"निष्पादित करें"</string> @@ -1451,7 +1460,7 @@ <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string> <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string> <string name="back_button_label" msgid="2300470004503343439">"वापस जाएं"</string> - <string name="next_button_label" msgid="1080555104677992408">"आगे"</string> + <string name="next_button_label" msgid="1080555104677992408">"आगे बढ़ें"</string> <string name="skip_button_label" msgid="1275362299471631819">"अभी नहीं"</string> <string name="no_matches" msgid="8129421908915840737">"कोई मिलान नहीं"</string> <string name="find_on_page" msgid="1946799233822820384">"पेज पर ढूंढें"</string> @@ -1639,7 +1648,7 @@ <string name="accessibility_shortcut_spoken_feedback" msgid="6143872712930414829">"मौजूदा सुलभता सुविधा शुरू करने के लिए \'सुलभता शॉर्टकट\' का फिर से इस्तेमाल करें"</string> <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"सुलभता बटन पर टैप करते समय इस्तेमाल की जाने वाली सुविधा चुनें:"</string> <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाओं में बदलाव करने के लिए, सुलभता बटन को दबाकर रखें."</string> - <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"बड़ा करें"</string> + <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"बड़ा करना"</string> <string name="user_switched" msgid="3768006783166984410">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string> <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा प्रस्थान किया जा रहा है…"</string> @@ -1879,7 +1888,7 @@ <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="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> <string name="demo_restarting_message" msgid="952118052531642451">"डिवाइस पुन: रीसेट कर रहा है…"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index ff2afba876c9..2747521d38bd 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -450,6 +450,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Aplikaciji omogućuje pristup telefonskim značajkama uređaja. Ta dozvola aplikaciji omogućuje utvrđivanje telefonskog broja i ID-ova uređaja, je li poziv aktivan te udaljeni broj koji je povezan pozivom."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"preusmjeravati pozive putem sustava"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Omogućuje aplikaciji da preusmjerava pozive putem sustava radi poboljšanja doživljaja."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"vidjeti i kontrolirati pozive putem sustava."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Omogućuje aplikaciji da vidi i kontrolira pozive koji su u tijeku na uređaju. To uključuje podatke kao što su brojevi i stanja poziva."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"nastaviti poziv iz neke druge aplikacije"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Omogućuje aplikaciji da nastavi poziv započet u nekoj drugoj aplikaciji."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitati telefonske brojeve"</string> @@ -510,6 +512,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Aplikaciji omogućuje komunikaciju s oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja zaslona"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji omogućuje onemogućavanje zaključavanja tipkovnice i svih pripadajućih sigurnosnih zaporki. Na primjer, telefon onemogućuje zaključavanje tipkovnice kod primanja dolaznog telefonskog poziva, nakon kojeg se zaključavanje tipkovnice ponovo omogućuje."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"dohvatiti i zahtijevati složenost zaključavanja zaslona"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Omogućuje aplikaciji da sazna razinu složenosti zaključavanja zaslona (visoka, srednja, niska ili nijedna), što upućuje na mogući raspon duljine i vrstu zaključavanja zaslona. Aplikacija također korisnicima može predložiti da ažuriraju zaključavanje zaslona na određenu razinu, no korisnici to mogu slobodno zanemariti i nastaviti dalje. Napominjemo da se zaključavanje zaslona ne pohranjuje u običnom tekstu, pa aplikacija ne zna točnu zaporku."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"koristiti biometrijski hardver"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Aplikaciji omogućuje upotrebu biometrijskog hardvera radi autentifikacije"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje hardverom za čitanje otisaka prstiju"</string> @@ -1103,26 +1107,26 @@ <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string> <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje s tekstom"</string> - <string name="email" msgid="4560673117055050403">"E-pošta"</string> - <string name="email_desc" msgid="3638665569546416795">"Slanje e-poruke na odabranu adresu"</string> - <string name="dial" msgid="1253998302767701559">"Poziv"</string> - <string name="dial_desc" msgid="6573723404985517250">"Pozivanje odabranog telefonskog broja"</string> - <string name="map" msgid="5441053548030107189">"Karta"</string> - <string name="map_desc" msgid="1836995341943772348">"Prikaz odabrane adrese na karti"</string> + <string name="email" msgid="4560673117055050403">"Pošalji e-poštu"</string> + <string name="email_desc" msgid="3638665569546416795">"Pošalji e-poštu na odabranu adresu"</string> + <string name="dial" msgid="1253998302767701559">"Nazovi"</string> + <string name="dial_desc" msgid="6573723404985517250">"Nazovi odabrani telefonski broj"</string> + <string name="map" msgid="5441053548030107189">"Prikaži na karti"</string> + <string name="map_desc" msgid="1836995341943772348">"Prikaži odabrane adrese na karti"</string> <string name="browse" msgid="1245903488306147205">"Otvori"</string> - <string name="browse_desc" msgid="8220976549618935044">"Otvaranje odabranog URL-a"</string> - <string name="sms" msgid="4560537514610063430">"Poruka"</string> - <string name="sms_desc" msgid="7526588350969638809">"Slanje poruke na odabrani telefonski broj"</string> + <string name="browse_desc" msgid="8220976549618935044">"Otvori odabrani URL"</string> + <string name="sms" msgid="4560537514610063430">"Pošalji poruku"</string> + <string name="sms_desc" msgid="7526588350969638809">"Pošalji poruku na odabrani telefonski broj"</string> <string name="add_contact" msgid="7867066569670597203">"Dodaj"</string> - <string name="add_contact_desc" msgid="4830217847004590345">"Dodavanje u kontakte"</string> + <string name="add_contact_desc" msgid="4830217847004590345">"Dodaj u kontakte"</string> <string name="view_calendar" msgid="979609872939597838">"Prikaži"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"Prikaz odabranog vremena u kalendaru"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Raspored"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"Zakazivanje događaja za određeno vrijeme"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"Prikaži odabrano vrijeme u kalendaru"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Zakaži"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"Zakaži događaj za određeno vrijeme"</string> <string name="view_flight" msgid="7691640491425680214">"Prati"</string> - <string name="view_flight_desc" msgid="3876322502674253506">"Praćenje odabranog leta"</string> + <string name="view_flight_desc" msgid="3876322502674253506">"Prati odabrani let"</string> <string name="translate" msgid="9218619809342576858">"Prevedi"</string> - <string name="translate_desc" msgid="4502367770068777202">"Prevedite odabrani tekst"</string> + <string name="translate_desc" msgid="4502367770068777202">"Prevedi odabrani tekst"</string> <string name="define" msgid="7394820043869954211">"Definiraj"</string> <string name="define_desc" msgid="7910883642444919726">"Definiraj odabrani tekst"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string> @@ -1201,6 +1205,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet se ažurira…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Uređaj se ažurira…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon se pokreće…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Pokretanje Androida..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet se pokreće…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Uređaj se pokreće…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje pohrane."</string> @@ -1261,6 +1266,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Povezani ste s Wi‑Fi mrežom koju je predložila aplikacija <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Želite li dopustiti da vam aplikacija <xliff:g id="NAME">%s</xliff:g> predlaže mreže?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se uključiti automatski"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini spremljene mreže visoke kvalitete"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Više ne uključuj"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 59d51237c70c..10538f402aa0 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen az eszköz telefonálási funkcióihoz. Az engedéllyel rendelkező alkalmazás meghatározhatja a telefonszámot és eszközazonosítókat, hogy egy hívás aktív-e, valamint híváskor a másik fél telefonszámát."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"rendszeren keresztüli hívásirányítás"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"A telefonálási élmény javítása érdekében lehetővé teszi az alkalmazás számára a rendszeren keresztüli hívásirányítást."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Hívások megtekintése és vezérlése a rendszeren keresztül"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Engedélyezi az alkalmazásnak az eszközön folyamatban lévő hívások megtekintését és vezérlését. Ebbe beletartoznak az olyan információk is, mint a hívásban részt vevő felek hívószáma és a hívások állapota."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"Másik alkalmazásból indított hívás folytatása"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Engedélyezi az alkalmazásnak, hogy folytassa a hívást, amelyet valamelyik másik alkalmazásban kezdtek meg."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"telefonszámok olvasása"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Lehetővé teszi az alkalmazás számára, hogy NFC (Near Field Communication - kis hatósugarú vezeték nélküli kommunikáció) technológiát használó címkékkel, kártyákkal és leolvasókkal kommunikáljon."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"képernyőzár kikapcsolása"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lehetővé teszi az alkalmazás számára a billentyűzár és bármely kapcsolódó jelszavas védelem kikapcsolását. Például a telefon feloldja a billentyűzárat bejövő hívás esetén, majd újra bekapcsolja azt a hívás végeztével."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"a képernyőzár összetettségének lekérdezése és lekérése"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Lehetővé teszi az alkalmazás számára, hogy megismerje a képernyőzár összetettségi szintjét (magas, közepes, alacsony vagy nincs), amely jelzi a képernyőzár lehetséges típusát és hosszát. Az alkalmazás ezenkívül javaslatot tehet a felhasználóknak a képernyőzár bizonyos szintre való frissítésére, de ezt a javaslatot a felhasználók figyelmen kívül hagyhatják. A képernyőzárat nem egyszerű szöveges formátumban tárolja a rendszer, ezért az alkalmazás nem fogja tudni a pontos jelszót."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrikus hardver használata"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Lehetővé teszi az alkalmazás számára a biometrikus hardver hitelesítésre való használatát"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ujjlenyomat-olvasó hardver kezelése"</string> @@ -1084,7 +1088,7 @@ <string name="inputMethod" msgid="1653630062304567879">"Beviteli mód"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Műveletek szöveggel"</string> <string name="email" msgid="4560673117055050403">"E-mail"</string> - <string name="email_desc" msgid="3638665569546416795">"Kiválasztott cím elküldése e-mailben"</string> + <string name="email_desc" msgid="3638665569546416795">"E-mail küldése a kiválasztott címre"</string> <string name="dial" msgid="1253998302767701559">"Hívás"</string> <string name="dial_desc" msgid="6573723404985517250">"Kiválasztott telefonszám hívása"</string> <string name="map" msgid="5441053548030107189">"Térkép"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"A táblagép frissítése…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Az eszköz frissítése…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"A telefon indítása…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Az Android indítása…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"A táblagép indítása…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Az eszköz indítása…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Tárhely-optimalizálás."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Összes hálózat"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Csatlakozva a(z) <xliff:g id="NAME">%s</xliff:g> által javasolt Wi-Fi-hálózathoz"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Szeretné, hogy a(z) <xliff:g id="NAME">%s</xliff:g> hálózatokat javasoljon Önnek?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Igen"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nem"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A Wi-Fi automatikusan bekapcsol"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Amikor jó minőségű mentett hálózat közelében tartózkodik"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne kapcsolódjon vissza"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index d019f0edbbef..fbb5f4b7122e 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Թույլ է տալիս հավելվածին օգտագործել սարքի հեռախոսային գործիքները: Այս թույլտվությունը հավելվածին հնարավորություն է տալիս որոշել հեռախոսահամարը և սարքի ID-ները, արդյոք զանգը ակտիվ է և միացված զանգի հեռակա հեռախոսահամարը:"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"զանգերն ուղարկել համակարգի միջոցով"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Հավելվածին թույլ է տալիս իր զանգերն ուղարկել համակարգի միջոցով՝ կապի որակը բարձրացնելու նպատակով։"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Զանգերի դիտում և վերահսկում համակարգի միջոցով"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Թույլ է տալիս հավելվածին տեսնել և վերահսկել ընթացիկ զանգերը սարքում: Սա ներառում է այնպիսի տեղեկություններ, ինչպիսիք են, օրինակ, հեռախոսահամարները և զանգերի վիճակը:"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"շարունակել զանգը այլ հավելվածի միջոցով"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Թույլ է տալիս հավելվածին շարունակել մեկ այլ հավելվածի միջոցով սկսած զանգը:"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"օգտագործել հեռախոսահամարները"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"էկրանի կողպման բարդության մակարդակի մասին տեղեկությունների և այդ մակարդակի բարձրացման հետ կապված խորհուրդների ստացում"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Հավելվածին հասանելի կդառնան էկրանի կողպման բարդության մակարդակի մասին տեղեկությունները (բարձր, միջին, ցածր կամ ոչ մի), այդ թվում կողպման տեսակի և գաղտնաբառի երկարության մասին տվյալները: Բացի այդ, հավելվածը կկարողանա առաջարկել օգտատերերին բարձրացնել կողպման բարդության մակարդակը: Օգտատերերը կարող են անտեսել այդ առաջարկները: Նկատի ունեցեք, որ գաղտնաբառը չի պահվում բաց տեքստի տեսքով և հասանելի չէ հավելվածին:"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"կենսաչափական սարքի օգտագործում"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Հավելվածին թույլ է տալիս օգտագործել նույնականացման համար նախատեսված կենսաչափական սարքը"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"կառավարել մատնահետքերի գրանցման սարքը"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Պլանշետը թարմացվում է…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Սարքը թարմացվում է…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Հեռախոսը միանում է…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android-ը մեկնարկում է…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Պլանշետը միանում է…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Սարքը միանում է…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Պահեստի օպտիմալացում:"</string> @@ -1239,6 +1244,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="1524719325616630906">"Միացել է «<xliff:g id="NAME">%s</xliff:g>» հավելվածի գտած Wi‑Fi ցանցին:"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Թույլատրե՞լ <xliff:g id="NAME">%s</xliff:g> հավելվածին առաջարկել ձեզ ցանցեր:"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Լավ ազդանշանով պահված ցանցի տարածքում գտնվելիս"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Նորից չմիացնել"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index cc70724833ed..3c6e3473a778 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Memungkinkan aplikasi mengakses fitur telepon perangkat. Izin ini memungkinkan aplikasi menentukan nomor telepon dan ID perangkat, apakah suatu panggilan aktif atau tidak, dan nomor jarak jauh yang tersambung oleh sebuah panggilan."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"sambungkan panggilan telepon melalui sistem"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Mengizinkan aplikasi menyambungkan panggilan telepon melalui sistem untuk menyempurnakan pengalaman menelepon."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"melihat dan mengontrol panggilan melalui sistem."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Memungkinkan aplikasi melihat dan mengontrol panggilan telepon yang sedang berlangsung di perangkat. Ini mencakup informasi seperti nomor yang menelepon dan status panggilan telepon."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"lanjutkan panggilan dari aplikasi lain"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Mengizinkan aplikasi melanjutkan panggilan yang dimulai di aplikasi lain."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"membaca nomor telepon"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Mengizinkan apl berkomunikasi dengan tag, kartu, dan alat pembaca Komunikasi Nirkabel Jarak Dekat (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"nonaktifkan kunci layar Anda"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Memungkinkan aplikasi menonaktifkan kunci tombol dan keamanan sandi apa pun yang terkait. Misalnya, ponsel menonaktifkan kunci tombol saat menerima panggilan telepon masuk, kemudian mengaktifkan kembali kunci tombol ketika panggilan selesai."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"dapatkan dan minta kompleksitas kunci layar"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Mengizinkan aplikasi mempelajari tingkat kompleksitas kunci layar (tinggi, sedang, rendah, atau tidak ada), yang menunjukkan kemungkinan rentang durasi dan jenis kunci layar. Aplikasi juga dapat menyarankan agar pengguna memperbarui kunci layar ke tingkat tertentu, tetapi pengguna dapat mengabaikan dan keluar dengan bebas. Perhatikan bahwa kunci layar tidak disimpan dalam teks biasa, sehingga aplikasi tidak mengetahui sandi yang sebenarnya."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"gunakan hardware biometrik"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Mengizinkan aplikasi menggunakan hardware biometrik untuk autentikasi"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"kelola hardware sidik jari"</string> @@ -1088,23 +1092,23 @@ <string name="dial" msgid="1253998302767701559">"Panggil"</string> <string name="dial_desc" msgid="6573723404985517250">"Panggil nomor telepon yang dipilih"</string> <string name="map" msgid="5441053548030107189">"Peta"</string> - <string name="map_desc" msgid="1836995341943772348">"Mencari alamat yang dipilih"</string> + <string name="map_desc" msgid="1836995341943772348">"Cari alamat yang dipilih"</string> <string name="browse" msgid="1245903488306147205">"Buka"</string> <string name="browse_desc" msgid="8220976549618935044">"Buka URL yang dipilih"</string> - <string name="sms" msgid="4560537514610063430">"Pesan"</string> - <string name="sms_desc" msgid="7526588350969638809">"Mengirimkan SMS ke nomor telepon yang dipilih"</string> + <string name="sms" msgid="4560537514610063430">"SMS"</string> + <string name="sms_desc" msgid="7526588350969638809">"Kirim SMS ke nomor telepon yang dipilih"</string> <string name="add_contact" msgid="7867066569670597203">"Tambahkan"</string> - <string name="add_contact_desc" msgid="4830217847004590345">"Menambahkan ke kontak"</string> + <string name="add_contact_desc" msgid="4830217847004590345">"Tambahkan ke kontak"</string> <string name="view_calendar" msgid="979609872939597838">"Lihat"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Melihat waktu yang dipilih di kalender"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Jadwal"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Jadwalkan"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Menjadwalkan acara untuk waktu yang dipilih"</string> - <string name="view_flight" msgid="7691640491425680214">"Lacak"</string> - <string name="view_flight_desc" msgid="3876322502674253506">"Memantau penerbangan yang dipilih"</string> + <string name="view_flight" msgid="7691640491425680214">"Pantau"</string> + <string name="view_flight_desc" msgid="3876322502674253506">"Pantau penerbangan yang dipilih"</string> <string name="translate" msgid="9218619809342576858">"Terjemahkan"</string> <string name="translate_desc" msgid="4502367770068777202">"Terjemahkan teks yang dipilih"</string> - <string name="define" msgid="7394820043869954211">"Tentukan"</string> - <string name="define_desc" msgid="7910883642444919726">"Tentukan teks yang dipilih"</string> + <string name="define" msgid="7394820043869954211">"Definisikan"</string> + <string name="define_desc" msgid="7910883642444919726">"Definisikan teks yang dipilih"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang penyimpanan hampir habis"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak dapat bekerja"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Penyimpanan tidak cukup untuk sistem. Pastikan Anda memiliki 250 MB ruang kosong, lalu mulai ulang."</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Mengupdate tablet…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Mengupdate perangkat…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Menyalakan ponsel…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Memulai Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Menyalakan tablet…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Menyalakan perangkat…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Mengoptimalkan penyimpanan."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap untuk melihat semua jaringan"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua jaringan"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Terhubung ke jaringan Wi‑Fi yang diusulkan oleh <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Perbolehkan <xliff:g id="NAME">%s</xliff:g> mengusulkan jaringan kepada Anda?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan aktif otomatis"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Saat berada di dekat jaringan berkualitas tinggi yang tersimpan"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Jangan aktifkan kembali"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 72ce56c09cf3..f638ff816f15 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Leyfir forriti að fá aðgang að símaeiginleikum tækisins. Þessi heimild gerir forritinu kleift að komast að símanúmeri og auðkennum tækisins, hvort símtal er í gangi og símanúmeri viðmælanda í símtali."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"senda símtöl gegnum kerfið"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Heimilar forritinu að senda símtöl sín gegnum kerfið til að bæta gæði símtalsins."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"sjá og stjórna símtölum í gegnum kerfið."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Leyfir forritinu að sjá og stjórna hringdum símtölum í tækinu. Þar á meðal eru upplýsingar á borð við símanúmer í símtölum og stöður símtala."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"halda áfram með símtal úr öðru forriti"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Leyfir forritinu að halda áfram með símtal sem hófst í öðru forriti."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lesa símanúmer"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Leyfir forriti að eiga samskipti við NFC-merki, -spjöld og -lesara (nándarsamskipti)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"slökkva á skjálásnum"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Leyfir forriti að slökkva á símalásnum og öðrum öryggisaðgerðum tengdum aðgangsorði. Til dæmis gerir síminn lásinn óvirkan þegar símtal berst og læsist svo aftur að símtali loknu."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"fá og biðja um flókinn skjálás"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Leyfir forritinu að læra hversu flókinn skjálásinn er (erfiður, miðlungs, léttur eða enginn), sem gefur til kynna lengd og tegund skjálássins. Forritið getur einnig lagt til að notendur geri skjálásinn flóknari upp að tilteknu marki, en notendur geta valið að hunsa það og halda áfram að vafra. Hafðu í huga að skjálásinn er ekki geymdur í ódulkóðuðum texta svo forritið veit ekki nákvæmt aðgangsorð."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"nota búnað fyrir líffræðileg gögn"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Leyfir forritinu að nota búnað fyrir líffræðileg gögn til auðkenningar"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"stjórna fingrafarabúnaði"</string> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"Eyða"</string> <string name="inputMethod" msgid="1653630062304567879">"Innsláttaraðferð"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaaðgerðir"</string> - <string name="email" msgid="4560673117055050403">"Tölvupóstur"</string> + <string name="email" msgid="4560673117055050403">"Senda tölvupóst"</string> <string name="email_desc" msgid="3638665569546416795">"Senda á valið netfang"</string> <string name="dial" msgid="1253998302767701559">"Símtal"</string> <string name="dial_desc" msgid="6573723404985517250">"Hringja í valið símanúmer"</string> @@ -1091,7 +1095,7 @@ <string name="map_desc" msgid="1836995341943772348">"Finna valið heimilisfang"</string> <string name="browse" msgid="1245903488306147205">"Opna"</string> <string name="browse_desc" msgid="8220976549618935044">"Opna valda vefslóð"</string> - <string name="sms" msgid="4560537514610063430">"Skilaboð"</string> + <string name="sms" msgid="4560537514610063430">"Senda skilaboð"</string> <string name="sms_desc" msgid="7526588350969638809">"Senda skilaboð í valið símanúmer"</string> <string name="add_contact" msgid="7867066569670597203">"Bæta við"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Bæta við tengiliði"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Uppfærir spjaldtölvu…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Uppfærir tæki…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Síminn kveikir á sér…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android er að ræsast…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Spjaldtölvan kveikir á sér…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Tækið kveikir á sér…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Fínstillir geymslu."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Öll netkerfi"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Tengt við Wi-Fi net sem <xliff:g id="NAME">%s</xliff:g> stakk upp á"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Viltu leyfa <xliff:g id="NAME">%s</xliff:g> að stinga upp á neti fyrir þig?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Já"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kveikt verður sjálfkrafa á Wi‑Fi"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Þegar þú ert nálægt vistuðu hágæðaneti"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ekki kveikja aftur"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 4463e11a8edf..c9c8f0c4039b 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Consente all\'applicazione di accedere alle funzioni telefoniche del dispositivo. Questa autorizzazione consente all\'applicazione di determinare il numero di telefono e gli ID dei dispositivi, se una chiamata è attiva e il numero remoto connesso da una chiamata."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"indirizzamento delle chiamate tramite il sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Consente all\'app di indirizzare le proprie chiamate tramite il sistema al fine di migliorare l\'esperienza di chiamata."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"visualizzazione e controllo delle chiamate tramite il sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Consente all\'app di visualizzare e controllare le chiamate in corso sul dispositivo. Sono incluse informazioni quali i numeri e lo stato relativi alle chiamate."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"Continuazione di una chiamata da un\'altra app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Consente all\'app di continuare una chiamata che è stata iniziata in un\'altra app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lettura dei numeri di telefono"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Consente all\'applicazione di comunicare con tag, schede e lettori NFC (Near Field Communication)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disattivazione blocco schermo"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Consente all\'applicazione di disattivare il blocco tastiera ed eventuali protezioni tramite password associate. Ad esempio, il telefono disattiva il blocco tastiera quando riceve una telefonata in arrivo e lo riattiva al termine della chiamata."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ricezione e richiesta della complessità del blocco schermo"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Consente all\'app di conoscere il livello di complessità del blocco schermo (alto, medio, basso o nessuno), che indica l\'intervallo di caratteri possibile e il tipo di blocco schermo. L\'app può inoltre suggerire agli utenti di aggiornare il blocco schermo a un livello specifico di complessità, ma gli utenti possono ignorare liberamente il suggerimento e uscire. Tieni presente che il blocco schermo non viene memorizzato come testo non crittografato, quindi l\'app non conosce la password esatta."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"Utilizzo di hardware biometrico"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Consente all\'app di utilizzare hardware biometrico per eseguire l\'autenticazione"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestisci hardware per il riconoscimento delle impronte digitali"</string> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"Elimina"</string> <string name="inputMethod" msgid="1653630062304567879">"Metodo inserimento"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Azioni testo"</string> - <string name="email" msgid="4560673117055050403">"Invia una email"</string> + <string name="email" msgid="4560673117055050403">"Invia email"</string> <string name="email_desc" msgid="3638665569546416795">"Invia un\'email all\'indirizzo selezionato"</string> <string name="dial" msgid="1253998302767701559">"Chiama"</string> <string name="dial_desc" msgid="6573723404985517250">"Chiama il numero di telefono selezionato"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Aggiornamento del tablet…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Aggiornamento del dispositivo…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Avvio del telefono…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Avvio di Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Avvio del tablet…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Avvio del dispositivo…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ottimizzazione archiviazione."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tutte le reti"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"È stata stabilita la connessione alla rete Wi‑Fi proposta da <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Vuoi consentire all\'app <xliff:g id="NAME">%s</xliff:g> di proporti reti?"</string> + <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">"Il Wi‑Fi verrà attivato automaticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando ti trovi nell\'area di una rete salvata di alta qualità"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Non riattivare"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 3f0c0b8adb62..26f6988fd528 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"מאפשר לאפליקציה לגשת לתכונות הטלפון של המכשיר. אישור זה מתיר לאפליקציה לגלות את מספר הטלפון ואת זיהויי המכשיר, האם שיחה פעילה ואת המספר המרוחק המחובר באמצעות שיחה."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ניתוב שיחות דרך המערכת"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"מאפשרת לאפליקציה לנתב את השיחות דרך המערכת כדי לשפר את חוויית השיחה."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ניתן להציג שיחות ולשלוט בהן באמצעות המערכת."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"מאפשר לאפליקציה להציג שיחות נוכחיות ולשלוט בהן במכשיר. זה כולל פרטים כמו מספרי שיחה של שיחות ומצב השיחה."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"המשך שיחה מאפליקציה אחרת"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"הרשאה זו מתירה לאפליקציה להמשיך שיחה שהחלה באפליקציה אחרת."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"גישה למספרי הטלפון"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"מאפשר לאפליקציה נהל תקשורת עם תגים, כרטיסים וקוראים מסוג \'תקשורת מטווח קצר\'."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ביטול נעילת המסך שלך"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"מאפשר לאפליקציה להשבית את נעילת המקשים וכל אמצעי אבטחה משויך המבוסס על סיסמה. לדוגמה, הטלפון משבית את נעילת המקשים בעת קבלה של שיחת טלפון נכנסת, ולאחר מכן מפעיל מחדש את נעילת המקשים עם סיום השיחה."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"קבלה ובקשה של מורכבות לנעילת מסך"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"מאפשרת לאפליקציה ללמוד את רמת המורכבות של נעילת המסך (גבוהה, בינונית, נמוכה או ללא). רמה זו מציינת את הטווח האפשרי של אורך וסוג של נעילת המסך. האפליקציה יכולה גם להציע למשתמשים שיעדכנו את נעילת המסך ברמה מסוימת, אבל המשתמשים יכולים להתעלם מההצעה ולנווט לפריט אחר כרצונם. יש לשים לב שנעילת המסך לא מאוחסנת ב-plaintext, ולכן האפליקציה לא יודעת מה הסיסמה המדויקת."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"שימוש בחומרה ביומטרית"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"מאפשרת לאפליקציה להשתמש בחומרה ביומטרית לצורך אימות"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ניהול חומרה של טביעות אצבעות"</string> @@ -1123,28 +1127,28 @@ <string name="deleteText" msgid="6979668428458199034">"מחיקה"</string> <string name="inputMethod" msgid="1653630062304567879">"שיטת קלט"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string> - <string name="email" msgid="4560673117055050403">"אימייל"</string> + <string name="email" msgid="4560673117055050403">"התכתבות באימייל"</string> <string name="email_desc" msgid="3638665569546416795">"שליחת אימייל לכתובת שנבחרה"</string> - <string name="dial" msgid="1253998302767701559">"שיחה"</string> + <string name="dial" msgid="1253998302767701559">"ביצוע שיחה"</string> <string name="dial_desc" msgid="6573723404985517250">"התקשרות למספר הטלפון שנבחר"</string> - <string name="map" msgid="5441053548030107189">"מפה"</string> - <string name="map_desc" msgid="1836995341943772348">"מיקום הכתובת שנבחרה"</string> + <string name="map" msgid="5441053548030107189">"צפייה במפה"</string> + <string name="map_desc" msgid="1836995341943772348">"איתור הכתובת שנבחרה"</string> <string name="browse" msgid="1245903488306147205">"פתיחה"</string> <string name="browse_desc" msgid="8220976549618935044">"פתיחה של כתובת האתר שנבחרה"</string> - <string name="sms" msgid="4560537514610063430">"הודעה"</string> + <string name="sms" msgid="4560537514610063430">"התכתבות בהודעות"</string> <string name="sms_desc" msgid="7526588350969638809">"שליחת הודעה למספר הטלפון שנבחר"</string> <string name="add_contact" msgid="7867066569670597203">"הוספה"</string> <string name="add_contact_desc" msgid="4830217847004590345">"הוספה לאנשי הקשר"</string> - <string name="view_calendar" msgid="979609872939597838">"תצוגה"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"הצגת הזמן שנבחר ביומן"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"לוח זמנים"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"תזמון אירוע לזמן שנבחר"</string> + <string name="view_calendar" msgid="979609872939597838">"צפייה"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"הצגת התאריך שנבחר ביומן"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"קביעת מועד"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"קביעת מועד לאירוע בתאריך שנבחר"</string> <string name="view_flight" msgid="7691640491425680214">"מעקב"</string> - <string name="view_flight_desc" msgid="3876322502674253506">"ניהול מעקב אחר הטיסה שנבחרה"</string> + <string name="view_flight_desc" msgid="3876322502674253506">"מעקב אחרי הטיסה שנבחרה"</string> <string name="translate" msgid="9218619809342576858">"תרגום"</string> <string name="translate_desc" msgid="4502367770068777202">"תרגום הטקסט שנבחר"</string> - <string name="define" msgid="7394820043869954211">"הגדרה"</string> - <string name="define_desc" msgid="7910883642444919726">"הגדרת הטקסט שנבחר"</string> + <string name="define" msgid="7394820043869954211">"מציאת הפירוש"</string> + <string name="define_desc" msgid="7910883642444919726">"פירוש הטקסט שנבחר"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"שטח האחסון אוזל"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"אין מספיק שטח אחסון עבור המערכת. ודא שיש לך שטח פנוי בגודל 250MB התחל שוב."</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"הטאבלט מתעדכן…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"הפעלת המכשיר מתחילה…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"הפעלת הטלפון מתחילה…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"הפעלת Android מתחילה…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"הפעלת הטאבלט מתחילה…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"הפעלת המכשיר מתחילה…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"מתבצעת אופטימיזציה של האחסון."</string> @@ -1283,6 +1288,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="1524719325616630906">"יש חיבור לרשת Wi‑Fi שהוצעה על ידי <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"האם ברצונך לקבל הצעות לרשתות מ-<xliff:g id="NAME">%s</xliff:g>?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"כשתימצאו בקרבת רשת באיכות גבוהה ששמרתם"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"אל תפעיל שוב"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index e069e333ec5f..45587cb7facb 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"端末の電話機能へのアクセスをアプリに許可します。これにより、電話番号、端末ID、通話中かどうか、通話相手の電話番号をアプリから特定できるようになります。"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"システム経由での通話転送"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"通話環境の改善のために、システム経由での通話転送をアプリに許可します。"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"システム経由の通話の表示と操作。"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"デバイスで進行中の通話の表示と操作をアプリに許可します。通話の電話番号や状態などの情報も含まれます。"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"別のアプリでの通話の続行"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"別のアプリで通話を続行することをこのアプリに許可します。"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"電話番号の読み取り"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"画面ロックの複雑さの入手とリクエスト"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"このアプリに画面ロックの複雑さレベル(高、中、低、なし)を認識することを許可します。複雑さレベルは、画面ロックの文字数の範囲やタイプを示すものです。アプリはユーザーに一定レベルまで画面ロックを更新するようすすめることもできますが、ユーザーは無視したり別の操作を行ったりできます。画面ロックは平文で保存されないため、アプリが正確なパスワードを知ることはありません。"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"生体認証ハードウェアの使用"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"生体認証ハードウェアを認証に使用することをアプリに許可します"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"指紋ハードウェアの管理"</string> @@ -1097,9 +1101,9 @@ <string name="add_contact_desc" msgid="4830217847004590345">"連絡先に追加します"</string> <string name="view_calendar" msgid="979609872939597838">"表示"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"カレンダーで選択した日時を表示します"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"スケジュール"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"予定を作成"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"選択した日時に予定を設定します"</string> - <string name="view_flight" msgid="7691640491425680214">"トラック"</string> + <string name="view_flight" msgid="7691640491425680214">"フライト"</string> <string name="view_flight_desc" msgid="3876322502674253506">"選択したフライトをチェックします"</string> <string name="translate" msgid="9218619809342576858">"翻訳"</string> <string name="translate_desc" msgid="4502367770068777202">"選択したテキストを翻訳します"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"タブレットの更新中…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"端末の更新中…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"スマートフォンの起動中…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Androidの起動中…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"タブレットの起動中…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"端末の起動中…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ストレージを最適化しています。"</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> で推奨される Wi-Fi ネットワークに接続"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"ネットワークを推奨することを <xliff:g id="NAME">%s</xliff:g> に許可しますか?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"高品質の保存済みネットワークの検出時"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"再度オンにしない"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 3be3093ee49e..07df9fc4ff75 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"აპს შეეძლება ჰქონდეს წვდომა მოწყობილობის სატელეფონო ფუნქციებზე. აპმა მსგავსი უფლებით შეძლებს დაადგინოს ტელეფონის ნომერი, მისი სერიული გამოცემა, აქტიური ზარი, დაკავშირებული ნომერი და მსგავსი."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ზარების სისტემის მეშვეობით მარშრუტიზაცია"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"დარეკვის ხარისხის გაუმჯობესების მიზნით, აპს ზარების სისტემის მეშვეობით მარშრუტიზაციის საშუალებას აძლევს."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ზარების ნახვა და გაკონტროლება სისტემის მეშვეობით."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"საშუალებას აძლევს აპს, იხილოს და გააკონტროლოს მიმდინარე ზარები მოწყობილობაზე. აღნიშნული მოიცავს ისეთ ინფორმაციას, როგორიცაა ზარებთან დაკავშირებული აბონენტების ნომრები და ზარების მდგომარეობა."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ზარის სხვა აპიდან გაგრძელება"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"ნებას რთავს აპს, გააგრძელოს ზარი, რომელიც სხვა აპშია წამოწყებული."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ტელეფონის ნომრების წაკითხვა"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ეკრანის დაბლოკვის მეთოდის სირთულის მიღება და მოთხოვნა"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"საშუალებას აძლევს აპს, შეიტყოს ეკრანის დაბლოკვის მეთოდის სირთულე (მაღალი, საშუალო, დაბალი ან არანაირი), რისი მეშვეობითაც შესაძლებელია ეკრანის დაბლოკვის მეთოდის სიგრძის შესაძლო დიაპაზონისა და ტიპის განსაზღვრა. გარდა ამისა, აპს შეუძლია მომხმარებლებისთვის ეკრანის დაბლოკვის მეთოდის გარკვეულ დონემდე გაძლიერების შეთავაზება, თუმცა მომხმარებლებს შეეძლებათ აღნიშნული შეტყობინების უგულებელყოფა და სხვა ეკრანზე გადასვლა. გაითვალისწინეთ, რომ ეკრანის დაბლოკვის მეთოდი არ ინახება ჩვეულებრივი ტექსტის სახით, ამიტომ აპს არ ეცოდინება ზუსტი პაროლი."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ბიომეტრიული აპარატის გამოყენება"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"საშუალებას აძლევს აპს, ავტორიზაციისთვის გამოიყენოს ბიომეტრიული აპარატი"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"თითის ანაბეჭდის აპარატის მართვა"</string> @@ -1083,11 +1087,11 @@ <string name="deleteText" msgid="6979668428458199034">"წაშლა"</string> <string name="inputMethod" msgid="1653630062304567879">"შეყვანის მეთოდი"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"ქმედებები ტექსტზე"</string> - <string name="email" msgid="4560673117055050403">"ელფოსტა"</string> + <string name="email" msgid="4560673117055050403">"ელფოსტის გაგზავნა"</string> <string name="email_desc" msgid="3638665569546416795">"არჩეულ მისამართზე ელფოსტის გაგზავნა"</string> <string name="dial" msgid="1253998302767701559">"ზარი"</string> <string name="dial_desc" msgid="6573723404985517250">"არჩეულ ტელეფონის ნომერზე დარეკვა"</string> - <string name="map" msgid="5441053548030107189">"რუკა"</string> + <string name="map" msgid="5441053548030107189">"რუკის გახსნა"</string> <string name="map_desc" msgid="1836995341943772348">"არჩეული მისამართის მდებარეობის დადგენა"</string> <string name="browse" msgid="1245903488306147205">"გახსნა"</string> <string name="browse_desc" msgid="8220976549618935044">"არჩეული URL-ის გახსნა"</string> @@ -1097,9 +1101,9 @@ <string name="add_contact_desc" msgid="4830217847004590345">"დამატება"</string> <string name="view_calendar" msgid="979609872939597838">"ნახვა"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"არჩეული დროის კალენდარში ნახვა"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"განრიგი"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"დაგეგმვა"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"მოვლენის არჩეული დროისთვის დაგეგმვა"</string> - <string name="view_flight" msgid="7691640491425680214">"ჩანაწერი"</string> + <string name="view_flight" msgid="7691640491425680214">"მიდევნება"</string> <string name="view_flight_desc" msgid="3876322502674253506">"არჩეული ფრენისთვის თვალის მიდევნება"</string> <string name="translate" msgid="9218619809342576858">"თარგმნა"</string> <string name="translate_desc" msgid="4502367770068777202">"არჩეული ტექსტის თარგმნა"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"მიმდინარეობს ტაბლეტის განახლება…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"მიმდინარეობს მოწყობილობის განახლება…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"მიმდინარეობს ტელეფონის ჩართვა…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android იწყება…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"მიმდინარეობს ტაბლეტის ჩართვა…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"მიმდინარეობს მოწყობილობის ჩართვა…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"მეხსიერების ოპტიმიზირება."</string> @@ -1239,6 +1244,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="1524719325616630906">"დაკავშირებულია <xliff:g id="NAME">%s</xliff:g>-ის მიერ შემოთავაზებულ Wi‑Fi ქსელთან"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"გსურთ, საშუალება მისცეთ <xliff:g id="NAME">%s</xliff:g>-ს, შემოგთავაზოთ ქსელები?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"როცა შენახულ მაღალხარისხიან ქსელებთან ახლოს იმყოფებით"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ხელახლა ნუ ჩართავ"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 0b4ff1cb55be..c622094f3e26 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Қолданбаға құрылғыдағы телефон функцияларына кіру мүмкіндігін береді. Бұл рұқсат қолданбаға телефон нөмірі, құрылғы жеке анықтағышы, қоңырау белсенділігі және сол қоңырауға байланысты қашықтағы нөмірді анықтау мүмкіндігін береді."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"қоңырауларды жүйе арқылы бағыттау"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Қоңырау шалу тәжірибесін жақсарту үшін қолданба қоңырауларды жүйе арқылы бағыттай алады."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"жүйе арқылы қоңырауларды көру және басқару."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Қолданбаға құрылғыдағы қазіргі қоңырауларды көруге және басқаруға мүмкіндік береді. Бұл – қоңырау шалу нөмірлері және қоңыраулардың күйі сияқты ақпаратқа қатысты."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"басқа қолданбадағы қоңырауды жалғастыру"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Қолданбаға басқа қолданбадағы қоңырауды жалғастыруға рұқсат береді."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"телефон нөмірлерін оқу"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"экранды құлыптау күрделілігі туралы дерек алу және оны сұрау"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Қолданбаға экранды құлыптау күрделілігінің деңгейін (жоғары, орташа, төмен немесе жоқ), соның ішінде ұзақтығы мен түрін көрсетеді. Сонымен қатар қолданба пайдаланушыларға экранды құлыптауды белгілі бір деңгейге жаңартуды ұсынады. Бірақ бұл ұсыныстарды елемеуге болады. Экранды құлпы қарапайым мәтін түрінде сақталмайтынын және қолданбаға белгісіз болатынын ескеріңіз."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"биометрикалық жабдықты пайдалану"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Аутентификациялау үшін қолданбаға биометрикалық жабдықты пайдалануға рұқсат береді"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"саусақ ізі жабдығын басқару"</string> @@ -1083,23 +1087,23 @@ <string name="deleteText" msgid="6979668428458199034">"Жою"</string> <string name="inputMethod" msgid="1653630062304567879">"Енгізу әдісі"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Мәтін әрекеттері"</string> - <string name="email" msgid="4560673117055050403">"Электрондық пошта"</string> - <string name="email_desc" msgid="3638665569546416795">"Таңдалған электрондық пошта мекенжайына хабар жіберу"</string> + <string name="email" msgid="4560673117055050403">"Эл. поштаны ашу"</string> + <string name="email_desc" msgid="3638665569546416795">"Таңдалған мекенжайға хабар жіберу"</string> <string name="dial" msgid="1253998302767701559">"Қоңырау шалу"</string> <string name="dial_desc" msgid="6573723404985517250">"Таңдалған телефон нөміріне қоңырау шалу"</string> - <string name="map" msgid="5441053548030107189">"Map"</string> - <string name="map_desc" msgid="1836995341943772348">"Таңдалған мекенжайдың орналасқан жерін анықтау"</string> + <string name="map" msgid="5441053548030107189">"Картаны ашу"</string> + <string name="map_desc" msgid="1836995341943772348">"Таңдалған мекенжайды табу"</string> <string name="browse" msgid="1245903488306147205">"Ашу"</string> <string name="browse_desc" msgid="8220976549618935044">"Таңдалған URL мекенжайын ашу"</string> - <string name="sms" msgid="4560537514610063430">"Хабар"</string> + <string name="sms" msgid="4560537514610063430">"Хабар жазу"</string> <string name="sms_desc" msgid="7526588350969638809">"Таңдалған телефон нөміріне хабар жіберу"</string> <string name="add_contact" msgid="7867066569670597203">"Енгізу"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Контактілер тізіміне енгізу"</string> <string name="view_calendar" msgid="979609872939597838">"Көру"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"Күнтізбеде таңдалған уақытты көру"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Кесте"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"Таңдалған уақытқа іс-шараны жоспарлау"</string> - <string name="view_flight" msgid="7691640491425680214">"Бақылау"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"Таңдалған уақытты күнтізбеден көру"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Жоспарлау"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"Таңдалған уақытқа іс-шара жоспарлау"</string> + <string name="view_flight" msgid="7691640491425680214">"Қадағалау"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Таңдалған ұшу рейсін қадағалау"</string> <string name="translate" msgid="9218619809342576858">"Аудару"</string> <string name="translate_desc" msgid="4502367770068777202">"Таңдалған мәтінді аудару"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Планшет жаңартылуда…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Құрылғы жаңартылуда…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Телефон іске қосылуда…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android іске қосылуда…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Планшет іске қосылуда…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Құрылғы іске қосылуда…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Қойманы оңтайландыру."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> ұсынған Wi‑Fi желісіне жалғанды"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> сізге желі ұсынғанын қалайсыз ба?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Сақталған жоғары сапалы желіге жақын болғанда"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Қайта қоспау"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index cd2af7bb65bf..ccc243d61edb 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ឲ្យកម្មវិធីចូលដំណើរការលក្ខណៈទូរស័ព្ទនៃឧបករណ៍។ សិទ្ធិនេះឲ្យកម្មវិធីកំណត់លេខទូរស័ព្ទ និងលេខសម្គាល់ឧបករណ៍ ថាតើការហៅសកម្ម និងលេខពីចម្ងាយបានភ្ជាប់ដោយការហៅ។"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"បញ្ជូនការហៅទូរសព្ទតាមរយៈប្រព័ន្ធ"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"អនុញ្ញាតឲ្យកម្មវិធីនេះបញ្ជូនការហៅទូរសព្ទរបស់វាតាមរយៈប្រព័ន្ធ ដើម្បីធ្វើឲ្យការហៅទូរសព្ទប្រសើរជាងមុន។"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"មើល និងគ្រប់គ្រងការហៅទូរសព្ទតាមរយៈប្រព័ន្ធ។"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"អនុញ្ញាតឱ្យកម្មវិធីមើល និងគ្រប់គ្រងការហៅទូរសព្ទដែលកំពុងដំណើរការនៅលើឧបករណ៍។ សកម្មភាពនេះរួមមានព័ត៌មានដូចជា លេខទូរសព្ទសម្រាប់ការហៅទូរសព្ទ និងស្ថានភាពនៃការហៅទូរសព្ទជាដើម។"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"បន្តការហៅទូរសព្ទពីកម្មវិធីផ្សេង"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"អនុញ្ញាតឱ្យកម្មវិធីបន្តការហៅទូរសព្ទ ដែលបានចាប់ផ្តើមនៅក្នុងកម្មវិធីផ្សេង។"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"អានលេខទូរសព្ទ"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ទទួល និងស្នើសុំភាពស្មុគស្មាញនៃការចាក់សោអេក្រង់"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"អនុញ្ញាតឱ្យកម្មវិធីរៀនអំពីកម្រិតស្មុគស្មាញការនៃការចាក់សោអេក្រង់ (ខ្ពស់ មធ្យម ទាប ឬគ្មាន) ដែលបញ្ជាក់អំពីប្រវែង និងប្រភេទនៃការចាក់សោអេក្រង់។ កម្មវិធីនេះក៏អាចណែនាំឱ្យអ្នកប្រើប្រាស់ធ្វើបច្ចុប្បន្នភាពការចាក់សោអេក្រង់ទៅកម្រិតជាក់លាក់ផងដែរ ប៉ុន្តែអ្នកប្រើប្រាស់អាចមិនអើពើនឹងការណែនាំនេះដោយសេរី។ សូមចំណាំថា ការចាក់សោអេក្រង់មិនត្រូវបានរក្សាទុកជាអត្ថបទធម្មតាទេ ដូច្នេះកម្មវិធីនេះមិនស្គាល់ពាក្យសម្ងាត់ពិតប្រាកដឡើយ។"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ប្រើឧបករណ៍ស្កេនស្នាមម្រាមដៃ"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"អនុញ្ញាតឱ្យកម្មវិធីប្រើឧបករណ៍ស្កេនស្នាមម្រាមដៃសម្រាប់ការផ្ទៀងផ្ទាត់"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"គ្រប់គ្រងផ្នែករឹងស្នាមម្រាមដៃ"</string> @@ -1183,6 +1187,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ថេប្លេតកំពុងដំឡើងជំនាន់…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ឧបករណ៍កំពុងដំឡើងជំនាន់…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ទូរសព្ទកំពុងចាប់ផ្ដើម…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android កំពុងចាប់ផ្ដើម…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ថេប្លេតកំពុងចាប់ផ្ដើម…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ឧបករណ៍កំពុងចាប់ផ្ដើម…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"កំពុងធ្វើឲ្យឧបករណ៍ផ្ទុកមានប្រសិទ្ធភាព។"</string> @@ -1241,6 +1246,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="1524719325616630906">"បានភ្ជាប់បណ្ដាញ Wi‑Fi ដែលបានណែនាំដោយ <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"តើអ្នកចង់អនុញ្ញាតឱ្យ <xliff:g id="NAME">%s</xliff:g> ណែនាំបណ្ដាញសម្រាប់អ្នកដែរទេ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"នៅពេលដែលអ្នកនៅជិតបណ្តាញគុណភាពខ្ពស់ដែលបានរក្សាទុក"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"កុំបើកឡើងវិញ"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 44010d280677..835070a5f7cd 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ಸಾಧನದ ಫೋನ್ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಫೋನ್ ಸಂಖ್ಯೆ ಮತ್ತು ಸಾಧನದ ID ಗಳನ್ನು ನಿರ್ಧರಿಸಲು, ಕರೆಯು ಸಕ್ರಿಯವಾಗಿದೆಯೇ ಮತ್ತು ಕರೆಯ ಮೂಲಕ ರಿಮೋಟ್ ಸಂಖ್ಯೆಯು ಸಂಪರ್ಕಗೊಂಡಿವೆಯೇ ಎಂಬುದನ್ನೂ ನಿರ್ಧರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಕಲ್ಪಿಸುತ್ತದೆ."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ಕರೆಗಳನ್ನು ಸಿಸ್ಟಂ ಮೂಲಕ ರವಾನಿಸಿ"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"ಕರೆಯ ಅನುಭವವನ್ನು ಸುಧಾರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ನ ಕರೆಗಳನ್ನು ಸಿಸ್ಟಂ ಮೂಲಕ ರವಾನಿಸಲು ಅನುಮತಿಸುತ್ತದೆ."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ಸಿಸ್ಟಂ ಮೂಲಕ ಕರೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ಸಾಧನದಲ್ಲಿನ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಮತ್ತು ನಿಯಂತ್ರಿಸಲು ಆ್ಯಪ್ ಅನುಮತಿಸುತ್ತದೆ. ಕರೆಗಳಿಗೆ ಸಂಬಂಧಿಸಿದ ಕರೆ ಸಂಖ್ಯೆಗಳು ಮತ್ತು ಕರೆ ಮಾಡಿದ ರಾಜ್ಯದಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿರುತ್ತದೆ."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ಮತ್ತೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಮೂಲಕ ಕರೆಯನ್ನು ಮುಂದುವರಿಸಿ"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"ಮತ್ತೊಂದು ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ಪ್ರಾರಂಭವಾದ ಕರೆಯನ್ನು ಮುಂದುವರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡಿ."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ಫೋನ್ ಸಂಖ್ಯೆಗಳನ್ನು ಓದಿ"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆಯನ್ನು ಪಡೆದುಕೊಳ್ಳಿ ಮತ್ತು ವಿನಂತಿಸಿ"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆ ಮಟ್ಟವನ್ನು ತಿಳಿದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ (ಹೆಚ್ಚು, ಮಧ್ಯಮ, ಅಥವಾ ಕಡಿಮೆ ಯಾವುದೂ ಅಲ್ಲ), ಇದು ಉದ್ದದ ಸಂಭವನೀಯ ಶ್ರೇಣಿ ಮತ್ತು ಸ್ಕ್ರೀನ್ ಲಾಕ್ನ ವಿಧವನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಬಳಕೆದಾರರು ನಿರ್ದಿಷ್ಟ ಮಟ್ಟದವರೆಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು ಎಂಬುದಾಗಿ ಕೂಡ ಆ್ಯಪ್ ಬಳಕೆದಾರರಿಗೆ ಸಲಹೆ ಮಾಡುತ್ತದೆ ಆದರೆ ಬಳಕೆದಾರರು ಮುಕ್ತವಾಗಿ ತಿರಸ್ಕರಿಸಬಹುದು ಮತ್ತು ನ್ಯಾವಿಗೇಟ್ ಮಾಡಬಹುದು. ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಖಾಲಿಪಠ್ಯದಲ್ಲಿ ಸಂಗ್ರಹಿಸಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸಿ ಇದರಿಂದ ಆ್ಯಪ್ಗೆ ಸರಿಯಾದ ಪಾಸ್ವರ್ಡ್ ಗೊತ್ತಿರುವುದಿಲ್ಲ."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್ವೇರ್ ಬಳಸಿ"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್ವೇರ್ ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ಬೆರಳಚ್ಚು ಹಾರ್ಡ್ವೇರ್ ನಿರ್ವಹಿಸಿ"</string> @@ -1083,25 +1087,25 @@ <string name="deleteText" msgid="6979668428458199034">"ಅಳಿಸಿ"</string> <string name="inputMethod" msgid="1653630062304567879">"ಇನ್ಪುಟ್ ವಿಧಾನ"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"ಪಠ್ಯದ ಕ್ರಮಗಳು"</string> - <string name="email" msgid="4560673117055050403">"ಇಮೇಲ್"</string> + <string name="email" msgid="4560673117055050403">"ಇಮೇಲ್ ಮಾಡಿ"</string> <string name="email_desc" msgid="3638665569546416795">"ಆಯ್ಕೆಮಾಡಿದ ವಿಳಾಸಕ್ಕೆ ಇಮೇಲ್ ಮಾಡಿ"</string> - <string name="dial" msgid="1253998302767701559">"ಕರೆ"</string> + <string name="dial" msgid="1253998302767701559">"ಕರೆ ಮಾಡಿ"</string> <string name="dial_desc" msgid="6573723404985517250">"ಆಯ್ಕೆಮಾಡಿದ ಫೋನ್ ಸಂಖ್ಯೆಗೆ ಕರೆ ಮಾಡಿ"</string> <string name="map" msgid="5441053548030107189">"ನಕ್ಷೆ"</string> <string name="map_desc" msgid="1836995341943772348">"ಆಯ್ಕೆ ಮಾಡಿದ ವಿಳಾಸವನ್ನು ಗುರುತಿಸಿ"</string> - <string name="browse" msgid="1245903488306147205">"ತೆರೆ"</string> + <string name="browse" msgid="1245903488306147205">"ತೆರೆಯಿರಿ"</string> <string name="browse_desc" msgid="8220976549618935044">"ಆಯ್ಕೆ ಮಾಡಿದ URL ತೆರೆಯಿರಿ"</string> - <string name="sms" msgid="4560537514610063430">"ಸಂದೇಶ"</string> + <string name="sms" msgid="4560537514610063430">"ಸಂದೇಶ ಕಳುಹಿಸಿ"</string> <string name="sms_desc" msgid="7526588350969638809">"ಆಯ್ಕೆಮಾಡಿದ ಫೋನ್ ಸಂಖ್ಯೆಗೆ ಸಂದೇಶ ಕಳುಹಿಸಿ"</string> <string name="add_contact" msgid="7867066569670597203">"ಸೇರಿಸಿ"</string> <string name="add_contact_desc" msgid="4830217847004590345">"ಸಂಪರ್ಕಗಳಿಗೆ ಸೇರಿಸಿ"</string> <string name="view_calendar" msgid="979609872939597838">"ವೀಕ್ಷಿಸಿ"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"ಕ್ಯಾಲೆಂಡರ್ನಲ್ಲಿ ಆಯ್ಕೆಮಾಡಿದ ಸಮಯವನ್ನು ವೀಕ್ಷಿಸಿ"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"ಅವಧಿ"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"ಆಯ್ಕೆ ಮಾಡಿದ ಸಮಯಕ್ಕೆ ಈವೆಂಟ್ ನಿಗದಿಪಡಿಸಿ"</string> - <string name="view_flight" msgid="7691640491425680214">"ಟ್ರ್ಯಾಕ್"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"ಸಮಯ ನಿಗದಿಗೊಳಿಸಿ"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"ಆಯ್ಕೆ ಮಾಡಿದ ಸಮಯಕ್ಕೆ ಈವೆಂಟ್ ನಿಗದಿಗೊಳಿಸಿ"</string> + <string name="view_flight" msgid="7691640491425680214">"ಟ್ರ್ಯಾಕ್ ಮಾಡಿ"</string> <string name="view_flight_desc" msgid="3876322502674253506">"ಆಯ್ಕೆಮಾಡಿದ ವಿಮಾನವನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಿ"</string> - <string name="translate" msgid="9218619809342576858">"ಅನುವಾದ"</string> + <string name="translate" msgid="9218619809342576858">"ಅನುವಾದ ಮಾಡಿ"</string> <string name="translate_desc" msgid="4502367770068777202">"ಆಯ್ಕೆಮಾಡಿದ ಪಠ್ಯವನ್ನು ಅನುವಾದಿಸಿ"</string> <string name="define" msgid="7394820043869954211">"ವಿವರಿಸಿ"</string> <string name="define_desc" msgid="7910883642444919726">"ಆಯ್ಕೆಮಾಡಿದ ಪಠ್ಯವನ್ನು ವಿವರಿಸಿ"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ಸಾಧನವನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ಫೋನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ಟ್ಯಾಬ್ಲೆಟ್ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ಸಾಧನವನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ಸಂಗ್ರಹಣೆಯನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> ಅವರಿಂದ ಸೂಚಿತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> ಅವರು ನಿಮಗಾಗಿ ನೆಟ್ವರ್ಕ್ಗಳನ್ನು ಪ್ರಸ್ತಾಪಿಸುವುದೇ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ನೀವು ಉಳಿಸಿದ ಅಧಿಕ ಗುಣಮಟ್ಟದ ನೆಟ್ವರ್ಕ್ ಸಮೀಪದಲ್ಲಿದ್ದಾಗ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ಮತ್ತೆ ಆನ್ ಮಾಡಲು ಹಿಂತಿರುಗಬೇಡಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index bdc50bfc08cb..888681552796 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"앱이 기기의 휴대전화 기능에 접근할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 전화번호 및 기기의 ID, 활성 통화인지 여부, 통화가 연결된 원격 번호 등을 확인할 수 있습니다."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"시스템을 통해 통화 연결"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"통화 환경을 개선하기 위해 앱이 시스템을 통해 통화를 연결하도록 허용합니다."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"시스템을 통해 통화 확인 및 제어"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"앱이 기기에서 진행 중인 통화를 확인 및 제어하도록 허용합니다. 여기에는 통화에 사용된 전화번호 및 통화 상태 등의 정보가 포함됩니다."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"다른 앱에서 전화 받기"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"다른 앱에서 수신한 전화를 계속하려면 앱을 허용합니다."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"전화번호 읽기"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"화면 잠금 복잡도 확인 및 요청"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"앱이 화면 잠금 길이와 유형의 가능한 범위를 나타내는 잠금 화면 복잡도 수준(높음, 보통, 낮음 또는 없음)을 파악하도록 허용합니다. 앱이 사용자에게 화면 잠금을 특정 수준으로 업데이트할 것을 제안할 수도 있지만, 사용자는 자유롭게 이를 무시하고 다른 곳으로 이동할 수 있습니다. 화면 잠금은 일반 텍스트로 저장되지 않으므로 앱에서 정확한 비밀번호를 알 수 없습니다."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"생체 인식 하드웨어 사용"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"앱에서 생체 인식 하드웨어를 인증에 사용하도록 허용합니다."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"지문 하드웨어 관리"</string> @@ -1096,9 +1100,9 @@ <string name="add_contact" msgid="7867066569670597203">"추가"</string> <string name="add_contact_desc" msgid="4830217847004590345">"연락처에 추가"</string> <string name="view_calendar" msgid="979609872939597838">"보기"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"캘린더에서 선택한 시간 보기"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"일정"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"선택한 시간의 일정 예약"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"선택한 시간 캘린더에서 보기"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"일정 만들기"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"선택한 시간으로 일정 만들기"</string> <string name="view_flight" msgid="7691640491425680214">"추적"</string> <string name="view_flight_desc" msgid="3876322502674253506">"선택한 항공편 추적"</string> <string name="translate" msgid="9218619809342576858">"번역"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"태블릿을 업데이트하는 중…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"기기를 업데이트하는 중…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"휴대전화를 시작하는 중…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android가 시작되는 중…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"태블릿을 시작하는 중…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"기기를 시작하는 중…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"저장소 최적화 중"</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g>에서 제안한 Wi‑Fi 네트워크에 연결됨"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g>에서 네트워크를 제안하도록 허용하시겠습니까?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"저장된 고품질 네트워크가 가까이 있는 경우"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"다시 사용 설정하지 않음"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index f6e9b7215960..de4974190d65 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Колдонмого түзмөктүн чалуу мүмкүнчүлүктөрүнө жетки алуу уруксатын берет. Бул уруксат колдонмого, телефондун номурун, түзмөктүн ID-син, чалуунун абалын жана байланышта чыккан номурду аныктоого жол берет."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"чалууларды тутум аркылуу өткөрүү"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Чалуунун сапатын жакшыртуу максатында колдонмого чалууларын тутум аркылуу өткөрүүгө уруксат берет."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"тутум аркылуу чалууларды көрүп, көзөмөлдөө."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Колдонмого түзмөктөгү аткарылып жаткан чалууларды көрүп, көзөмөлдөөгө уруксат берет. Буга чалуулардын саны жана абалы сыяктуу маалымат кирет."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"чалууну башка колдонмодон улантуу"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Башка колдонмодон аткарылган чалууну бул колдонмодо улантууга уруксат берүү."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"телефон номерлерин окуу"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"экранды бөгөттөө канчалык татаал экенин сурап, маалымат алуу"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Колдонмого экранды бөгөттөөнүн татаалдыгын (татаал, орточо, оңой же такыр жок) үйрөнүүгө мүмкүнчүлүк берет. Татаалдык деңгээли сырсөздүн узундугу жана экранды бөгөттөөнүн түрү боюнча айырмаланат. Колдонмо экранды бөгөттөөнү белгилүү деңгээлге тууралоону колдонуучуларга сунуштай да алат, бирок колдонуучулар ага көңүл бурбай койсо болот. Сырсөздү колдонмо билбеши үчүн, экранды бөгөттөө сырсөзүн кадимки текстте сактоого болбойт."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"биометрикалык аппаратты колдонуу"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Колдонмого аныктыгын текшерүү үчүн биометрикалык аппаратты пайдалануу мүмкүндүгүн берет"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"манжа изинин аппараттык камсыздоосун башкаруу"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Планшет жаңыртылууда…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Түзмөк жаңыртылууда…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Телефон күйгүзүлүүдө…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android жүргүзүлүүдө…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Планшет күйгүзүлүүдө…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Түзмөк күйүгүзүлүүдө…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Сактагыч ыңгайлаштырылууда."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> сунуштаган Wi‑Fi тармагына туташтырылды"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> сизге тармактарды сунуштай берсинби?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Байланыш сигналы күчтүү тармактарга жакындаганда"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Өзү кайра күйбөйт"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index e925d928d4d6..935630281e19 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງຄວາມສາມາດການໂທລະສັບຂອງອຸປະກອນ. ການກຳນົດສິດນີ້ເຮັດໃຫ້ແອັບຯສາມາດກວດສອບເບີໂທລະສັບ ແລະ ID ຂອງອຸປະກອນ, ບໍ່ວ່າການໂທຈະຍັງດຳເນີນຢູ່ ແລະເບີປາຍທາງເຊື່ອມຕໍ່ຢູ່ຫຼືບໍ່ກໍຕາມ."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"route calls through the system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Allows the app to route its calls through the system in order to improve the calling experience."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ເຫັນ ແລະ ຄວບຄຸມການໂທຜ່ານລະບົບ."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ອະນຸຍາດໃຫ້ແອັບເຫັນ ແລະ ຄວບຄຸມການໂທທີ່ກຳລັງດຳເນີນຢູ່ອຸປະກອນ. ນີ້ຮວມເຖິງຂໍ້ມູນ ເຊັ່ນ: ເບີໂທສຳລັບການໂທ ແລະ ສະຖານະຂອງການໂທນຳ."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ສືບຕໍ່ການໂທຈາກແອັບອື່ນ"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"ອະນຸຍາດໃຫ້ແອັບສືບຕໍ່ການໂທເຊິ່ງອາດຖືກເລີ່ມຕົ້ນໃນແອັບອື່ນ."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ອ່ານເບີໂທລະສັບ"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ຮັບ ແລະ ຂໍຄວາມຊັບຊ້ອນການລັອກໜ້າຈໍ"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ອະນຸຍາດໃຫ້ແອັບສຶກສາລະດັບຄວາມຊັບຊ້ອນຂອງໜ້າຈໍລັອກ (ສູງ, ກາງ ຫຼື ບໍ່ມີ), ເຊິ່ງລະບຸຂອບເຂດຄວາມເປັນໄປໄດ້ຂອງຄວາມຍາວ ແລະ ປະເພດຂອງການລັອກໜ້າຈໍ. ແອັບນີ້ສາມາດແນະນຳຜູ້ໃຊ້ວ່າເຂົາເຈົ້າສາມາດອັບເດດໜ້າຈໍລັອກເປັນລະດັບໃດໜຶ່ງເປັນການສະເພາະໄດ້, ແຕ່ຜູ້ໃຊ້ສາມາດທີ່ຈະບໍ່ສົນໃຈ ຫຼື ເປີດໄປອັນອື່ນໄດ້. ກະລຸນາຮັບຊາບວ່າການລັອກໜ້າຈໍບໍ່ໄດ້ບັນທຶກໃນແບບຂໍ້ຄວາມທຳມະດາ, ດັ່ງນັ້ນແອັບຈະບໍ່ຮູ້ລະຫັດຜ່ານທີ່ແນ່ນອນ."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ໃຊ້ຮາດແວຊີວະມິຕິ"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ອະນຸຍາດໃຫ້ແອັບນຳໃຊ້ຮາດແວຊີວະມິຕິສຳລັບການພິສູດຢືນຢັນ"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ຈັດການຮາດແວລາຍນີ້ວມື"</string> @@ -1097,9 +1101,9 @@ <string name="add_contact_desc" msgid="4830217847004590345">"ເພີ່ມໃສ່ລາຍຊື່ຜູ້ຕິດຕໍ່"</string> <string name="view_calendar" msgid="979609872939597838">"ເບິ່ງ"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"ເບິ່ງເວລາທີ່ເລືອກໃນປະຕິທິນ"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"ຕັ້ງເວລາ"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"ກຳນົດເວລາ"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"ກຳນົດເວລາສຳລັບເວລາທີ່ເລືອກ"</string> - <string name="view_flight" msgid="7691640491425680214">"ແທຣັກ"</string> + <string name="view_flight" msgid="7691640491425680214">"ຕິດຕາມ"</string> <string name="view_flight_desc" msgid="3876322502674253506">"ຕິດຕາມຖ້ຽວບິນທີ່ເລືອກ"</string> <string name="translate" msgid="9218619809342576858">"ແປພາສາ"</string> <string name="translate_desc" msgid="4502367770068777202">"ແປຂໍ້ຄວາມທີ່ເລືອກ"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ກຳລັງອັບເດດແທັບເລັດ…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ກຳລັງອັບເດດອຸປະກອນ…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ກຳລັງເລີ່ມໂທລະສັບ…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"ກຳລັງເລີ່ມລະບົບ Android …"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ກຳລັງເລີ່ມແທັບເລັດ…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ກຳລັງເລີ່ມອຸປະກອນ…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ການປັບບ່ອນເກັບຂໍ້ມູນໃຫ້ເໝາະສົມ."</string> @@ -1239,6 +1244,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="1524719325616630906">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ທີ່ສະເໜີໂດຍ <xliff:g id="NAME">%s</xliff:g> ແລ້ວ"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"ທ່ານຕ້ອງການໃຫ້ <xliff:g id="NAME">%s</xliff:g> ສະເໜີເຄືອຂ່າຍໃຫ້ທ່ານບໍ່?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ເມື່ອທ່ານຢູ່ໃກ້ເຄືອຂ່າຍຄຸນນະພາບສູງທີ່ບັນທຶກໄວ້"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ບໍ່ຕ້ອງເປີດໃຊ້ຄືນໃໝ່"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index ada983f876b2..8870ebb55941 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Leidžiama programai pasiekti telefono funkcijas įrenginyje. Šis leidimas suteikia teisę programai nustatyti telefono numerį ir įrenginio ID, tai, ar skambutis aktyvus, ir skambučiu prijungtą nuotolinį numerį."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"nukreipti skambučius per sistemą"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Programai leidžiama nukreipti jos skambučius per sistemą siekiant pagerinti skambinimo paslaugas."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"matyti ir valdyti skambučius per sistemą."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Programai leidžiama matyti ir valdyti vykstančius skambučius įrenginyje. Tai apima tokią informaciją kaip skambučių telefono numeriai ir skambučių būsena."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"tęsti skambutį naudojant kitą programą"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Programai leidžiama tęsti skambutį, kuris buvo pradėtas naudojant kitą programą."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"skaityti telefonų numerius"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Leidžiama programai perduoti artimojo lauko ryšių technologijos (ALR) žymas, korteles ir skaitymo programas."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"išjungti ekrano užraktą"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Leidžiama programai neleisti klavišo užrakto ir visos susijusios slaptažodžio apsaugos. Pvz., telefonas neleidžia klavišo užrakto priimant gaunamąjį skambutį ir pakartotinai jį įgalina, kai skambutis baigiamas."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"gauti ir pateikti ekrano užrakto sudėtingumo užklausą"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Leidžiama programai sužinoti ekrano užrakto sudėtingumo lygį (aukštas, vidutinis, žemas arba nėra), nurodantį galimą ekrano užrakto trukmės diapazoną ir tipą. Be to, programa gali pasiūlyti naudotojams atnaujinti ekrano užraktą į tam tikrą lygį, bet naudotojai gali laisvai nepaisyti ir išeiti. Atminkite, kad ekrano užraktas nesaugomas kaip grynasis tekstas, todėl programa nežino tikslaus slaptažodžio."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"naudoti biometrinę aparatinę įrangą"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Leidžiama programai naudoti biometrinę aparatinę įrangą tapatybei nustatyti"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"tvarkyti piršto antspaudo aparatinę įrangą"</string> @@ -1131,7 +1135,7 @@ <string name="map_desc" msgid="1836995341943772348">"Rasti vietą pasirinktu adresu"</string> <string name="browse" msgid="1245903488306147205">"Atidaryti"</string> <string name="browse_desc" msgid="8220976549618935044">"Atidaryti pasirinktą URL"</string> - <string name="sms" msgid="4560537514610063430">"Pranešimas"</string> + <string name="sms" msgid="4560537514610063430">"Rašyti pranešimą"</string> <string name="sms_desc" msgid="7526588350969638809">"Siųsti pranešimą pasirinktu telefono numeriu"</string> <string name="add_contact" msgid="7867066569670597203">"Pridėti"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Pridėti prie kontaktų"</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Planšetinis kompiuteris atnaujinamas…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Įrenginys atnaujinamas…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefonas paleidžiamas…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Paleidžiama „Android“…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Planšetinis kompiuteris paleidžiamas…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Įrenginys paleidžiamas…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizuojama saugykla."</string> @@ -1283,6 +1288,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tinklai"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Prisijungta prie „<xliff:g id="NAME">%s</xliff:g>“ pasiūlyto „Wi‑Fi“ tinklo"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Ar norite leisti „<xliff:g id="NAME">%s</xliff:g>“ siūlyti jums tinklus?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Taip"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"„Wi‑Fi“ bus įjungtas automatiškai"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kai būsite netoli išsaugoto aukštos kokybės tinklo"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Neįjunkite vėl"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index dd4b125681c4..5a1432b810e1 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -450,6 +450,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ļauj lietotnei piekļūt ierīces tālruņa funkcijām. Ar šo atļauju lietotne var noteikt tālruņa numuru un ierīču ID, zvana statusu un attālo numuru, ar ko ir izveidots savienojums, veicot zvanu."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"maršrutēt zvanus sistēmā"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Ļauj lietotnei maršrutēt tās zvanus sistēmā, lai uzlabotu zvanīšanas pieredzi."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"skatīt un kontrolēt zvanus sistēmā."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Ļauj lietotnei ierīcē skatīt un kontrolēt aktīvos zvanus. Šeit ir ietverta tāda informācija kā zvanu tālruņa numuri un zvanu statuss."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"turpināt zvanu no citas lietotnes"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Ļauj lietotnei turpināt zvanu, kas tika sākts citā lietotnē."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lasīt tālruņa numurus"</string> @@ -510,6 +512,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Ļauj lietotnei sazināties ar tuva darbības lauka sakaru (Near Field Communication — NFC) atzīmēm, kartēm un lasītājiem."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"atspējot ekrāna bloķēšanu"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ļauj lietotnei atspējot taustiņslēgu un visu saistīto paroļu drošību. Piemēram, tālrunis atspējo taustiņslēgu, saņemot ienākošu zvanu, un pēc zvana pabeigšanas atkārtoti iespējo taustiņslēgu."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"saņemt un pieprasīt informāciju par ekrāna bloķēšanas sarežģītību"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Atļauj lietotnei saglabāt informāciju par ekrāna bloķēšanas sarežģītības pakāpi (augsta, vidēja, zema, nav), kas apzīmē iespējamo garumu un ekrāna bloķēšanas veidus. Lietotnē lietotājiem var tikt rādīts arī ieteikums ekrāna bloķēšanai iestatīt citu līmeni, taču šo ieteikumu var ignorēt un aizvērt. Ņemiet vērā, ka ekrāna bloķēšanas informācija netiek glabāta vienkārša teksta formātā, tāpēc lietotnei nav piekļuves precīzai parolei."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"izmantot biometrisko datu aparatūru"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Atļauj lietotnei izmantot biometrisko datu aparatūru autentificēšanai"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"pārvaldīt pirkstu nospiedumu aparatūru"</string> @@ -1105,7 +1109,7 @@ <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksta darbības"</string> <string name="email" msgid="4560673117055050403">"E-pasts"</string> <string name="email_desc" msgid="3638665569546416795">"Nosūtīt e-pasta ziņojumu uz atlasīto adresi"</string> - <string name="dial" msgid="1253998302767701559">"Zvanīt"</string> + <string name="dial" msgid="1253998302767701559">"Zvans"</string> <string name="dial_desc" msgid="6573723404985517250">"Zvanīt uz atlasīto tālruņa numuru"</string> <string name="map" msgid="5441053548030107189">"Karte"</string> <string name="map_desc" msgid="1836995341943772348">"Atrast atlasīto adresi"</string> @@ -1201,6 +1205,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Notiek planšetdatora atjaunināšana…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Notiek ierīces atjaunināšana…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Notiek tālruņa palaišana…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Notiek Android palaišana…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Notiek planšetdatora palaišana…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Notiek ierīces palaišana…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Notiek krātuves optimizēšana."</string> @@ -1261,6 +1266,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tīkli"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Izveidots savienojums ar Wi-Fi tīklu, ko ieteica lietotne <xliff:g id="NAME">%s</xliff:g>."</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Vai vēlaties, lai lietotne <xliff:g id="NAME">%s</xliff:g> iesaka tīklus?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jā"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nē"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi tiks automātiski ieslēgts"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kad atrodaties saglabāta augstas kvalitātes tīkla tuvumā"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Neieslēgt atkārtoti"</string> diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml index c26bebe65a7a..0ae2b4d57be4 100644 --- a/core/res/res/values-mcc302-mnc220/config.xml +++ b/core/res/res/values-mcc302-mnc220/config.xml @@ -23,17 +23,4 @@ <integer name="config_mobile_mtu">1410</integer> - <!-- Values for GPS configuration (Telus) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>SUPL_HOST=supl.google.com</item> - <item>SUPL_PORT=7275</item> - <item>SUPL_VER=0x20000</item> - <item>SUPL_MODE=1</item> - <item>SUPL_ES=1</item> - <item>LPP_PROFILE=3</item> - <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>GPS_LOCK=3</item> - </string-array> - </resources> diff --git a/core/res/res/values-mcc302-mnc221/config.xml b/core/res/res/values-mcc302-mnc221/config.xml deleted file mode 100644 index 96338b589cd2..000000000000 --- a/core/res/res/values-mcc302-mnc221/config.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2013, 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. -*/ ---> - -<!-- These resources are around just to allow their values to be customized - for different hardware and product builds. --> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Values for GPS configuration (Telus) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>SUPL_HOST=supl.google.com</item> - <item>SUPL_PORT=7275</item> - <item>SUPL_VER=0x20000</item> - <item>SUPL_MODE=1</item> - <item>SUPL_ES=1</item> - <item>LPP_PROFILE=3</item> - <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>GPS_LOCK=3</item> - </string-array> - -</resources> diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml index 79f4bb6fdd0b..ef32acd925d1 100644 --- a/core/res/res/values-mcc302-mnc370/config.xml +++ b/core/res/res/values-mcc302-mnc370/config.xml @@ -24,17 +24,4 @@ --> <integer name="config_mobile_mtu">1410</integer> - <!-- Values for GPS configuration (Rogers) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>SUPL_HOST=supl.google.com</item> - <item>SUPL_PORT=7275</item> - <item>SUPL_VER=0x20000</item> - <item>SUPL_MODE=1</item> - <item>SUPL_ES=1</item> - <item>LPP_PROFILE=2</item> - <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>GPS_LOCK=3</item> - </string-array> - </resources> diff --git a/core/res/res/values-mcc302-mnc610/config.xml b/core/res/res/values-mcc302-mnc610/config.xml index 10b007e9850d..2b78f5586fb8 100644 --- a/core/res/res/values-mcc302-mnc610/config.xml +++ b/core/res/res/values-mcc302-mnc610/config.xml @@ -22,17 +22,4 @@ --> <integer name="config_mobile_mtu">1428</integer> - <!-- Values for GPS configuration (Bell) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>SUPL_HOST=supl.google.com</item> - <item>SUPL_PORT=7275</item> - <item>SUPL_VER=0x20000</item> - <item>SUPL_MODE=1</item> - <item>SUPL_ES=1</item> - <item>LPP_PROFILE=2</item> - <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>GPS_LOCK=3</item> - </string-array> - </resources> diff --git a/core/res/res/values-mcc302-mnc640/config.xml b/core/res/res/values-mcc302-mnc640/config.xml deleted file mode 100644 index 657d1e77c4ab..000000000000 --- a/core/res/res/values-mcc302-mnc640/config.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2013, 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"> - <!-- Values for GPS configuration (Bell) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>SUPL_HOST=supl.google.com</item> - <item>SUPL_PORT=7275</item> - <item>SUPL_VER=0x20000</item> - <item>SUPL_MODE=1</item> - <item>SUPL_ES=1</item> - <item>LPP_PROFILE=2</item> - <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>GPS_LOCK=3</item> - </string-array> - -</resources> diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml index ba8c75a179e9..7be9a1c5231f 100644 --- a/core/res/res/values-mcc302-mnc720/config.xml +++ b/core/res/res/values-mcc302-mnc720/config.xml @@ -24,17 +24,4 @@ --> <integer name="config_mobile_mtu">1430</integer> - <!-- Values for GPS configuration (Rogers) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>SUPL_HOST=supl.google.com</item> - <item>SUPL_PORT=7275</item> - <item>SUPL_VER=0x20000</item> - <item>SUPL_MODE=1</item> - <item>SUPL_ES=1</item> - <item>LPP_PROFILE=2</item> - <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>GPS_LOCK=3</item> - </string-array> - </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 8b73b99dd707..769ac435cafa 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Овозможува апликацијата да пристапи кон карактеристиките на телефонот на уредот. Оваа дозвола овозможува апликацијата да ги утврди телефонскиот број и ID на уредот, дали повикот е активен и далечинскиот број поврзан со повикот."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"пренасочи повици преку системот"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дозволете ѝ на апликацијата да ги пренасочи повиците преку системот за да го подобри искуството при јавувањето."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"гледање и контролирање повици преку системот."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Дозволува апликацијата да гледа и контролира тековни повици на уредот. Ова вклучува информации како телефонски броеви за повици и состојбата на повиците."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"продолжување повик од друга апликација"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Овозможува апликацијата да продолжи повик започнат на друга апликација."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"да чита телефонски броеви"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"добива и бара комплексност на заклучување екран"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Ѝ дозволува на апликацијата да го научи нивото на комплексност за заклучувањето на екранот (високо, средно, ниско или нема), коешто ги означува можниот опсег на должина и типот на заклувањето на екранот. Апликацијата може да им дава предлози на корисниците да го ажурираат заклучувањето на екранот на одредено ниво, но корисниците можат да го игнорираат и да продолжат понатаму. Имајте предвид дека заклучувањето на екранот не се складира како обичен текст па апликацијата не ја знае точната лозинка."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"користи биометриски хардвер"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дозволува апликацијата да користи биометриски хардвер за проверка"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управувај хардвер за отпечатоци"</string> @@ -1083,23 +1087,23 @@ <string name="deleteText" msgid="6979668428458199034">"Избриши"</string> <string name="inputMethod" msgid="1653630062304567879">"Метод на внес"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Дејства со текст"</string> - <string name="email" msgid="4560673117055050403">"E-пошта"</string> + <string name="email" msgid="4560673117055050403">"Испрати е-пошта"</string> <string name="email_desc" msgid="3638665569546416795">"Испраќа е-порака на избраната адреса"</string> <string name="dial" msgid="1253998302767701559">"Повикај"</string> <string name="dial_desc" msgid="6573723404985517250">"Го повикува избраниот телефонски број"</string> - <string name="map" msgid="5441053548030107189">"Карта"</string> + <string name="map" msgid="5441053548030107189">"Отвори карта"</string> <string name="map_desc" msgid="1836995341943772348">"Лоцирај ја избраната адреса"</string> <string name="browse" msgid="1245903488306147205">"Отвори"</string> <string name="browse_desc" msgid="8220976549618935044">"Ја отвора избраната URL"</string> - <string name="sms" msgid="4560537514610063430">"Порака"</string> + <string name="sms" msgid="4560537514610063430">"Испрати порака"</string> <string name="sms_desc" msgid="7526588350969638809">"Испраќа порака на избраниот телефонски број"</string> <string name="add_contact" msgid="7867066569670597203">"Додај"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Додава во контакти"</string> <string name="view_calendar" msgid="979609872939597838">"Прикажи"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Го гледа избраното време во календарот"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Распоред"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Закажи"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Закажува настан за избраното време"</string> - <string name="view_flight" msgid="7691640491425680214">"Песна"</string> + <string name="view_flight" msgid="7691640491425680214">"Следи го"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Следи избран лет"</string> <string name="translate" msgid="9218619809342576858">"Преведи"</string> <string name="translate_desc" msgid="4502367770068777202">"Преведете го избраниот текст"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Таблетот се ажурира…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Уредот се ажурира…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Телефонот стартува…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android стартува…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Таблетот стартува…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Уредот стартува…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимизирање на складирањето."</string> @@ -1239,6 +1244,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="1524719325616630906">"Поврзано на Wi‑Fi мрежа обезбедена од <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Дали сакате да дозволите <xliff:g id="NAME">%s</xliff:g> да ви предлага мрежи?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Кога сте во близина на зачувана мрежа со висок квалитет"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не вклучувај повторно"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 8c451a265d16..620718d42d7a 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ഉപകരണത്തിന്റെ ഫോൺ സവിശേഷതകൾ ആക്സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി ഫോൺ നമ്പർ, ഉപകരണ ഐഡികൾ, ഒരു കോൾ സജീവമാണോയെന്നത്, ഒരു കോൾ കണക്റ്റുചെയ്ത വിദൂര നമ്പർ എന്നിവ നിർണ്ണയിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"കോളുകൾ സിസ്റ്റത്തിലൂടെ വിടുക"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"കോളിംഗ് അനുഭവം മെച്ചപ്പെടുത്തുന്നതിനായി തങ്ങളുടെ കോളുകൾ സിസ്റ്റത്തിലേയ്ക്ക് വഴിതിരിച്ചുവിടാൻ ആപ്പുകളെ അനുവദിക്കുന്നു."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"സിസ്റ്റത്തിലൂടെ കോളുകൾ കാണുകയും നിയന്ത്രിക്കുകയും ചെയ്യുക."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ഉപകരണത്തിൽ നിലവിലുള്ള കോളുകൾ കാണാനും നിയന്തിക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു. കോളുകൾക്കുള്ള നമ്പറുകളും അവയുടെ നിലയും പോലെയുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"മറ്റൊരു ആപ്പിൽ നിന്നുള്ള കോൾ തുടരുക"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"മറ്റൊരു ആപ്പിൽ ആരംഭിച്ച കോൾ തുടരാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ഫോൺ നമ്പറുകൾ റീഡുചെയ്യൽ"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"സ്ക്രീൻ ലോക്ക് സങ്കീർണ്ണത അഭ്യർത്ഥിച്ച്, നേടുക"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"സ്ക്രീൻ ലോക്കിന്റെ സാധ്യമായ നീളവും തരവും സൂചിപ്പിക്കുന്ന, അതിന്റെ സങ്കീർണ്ണതാ നില (ഉയർന്നത്, ഇടത്തരം, കുറഞ്ഞത് അല്ലെങ്കിൽ ഒന്നുമില്ല) മനസിലാക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. സ്ക്രീൻ ലോക്ക് ഒരു പ്രത്യേക തലത്തിലേക്ക് അപ്ഡേറ്റ് ചെയ്യുന്ന ഉപയോക്താക്കൾക്ക് നിർദ്ദേശിക്കാനും ആപ്പിനാവും, മാത്രമല്ല ഉപയോക്താക്കൾക്ക് എളുപ്പത്തിൽ അവഗണിക്കാനും മറ്റൊന്നിലേക്ക് നാവിഗേറ്റ് ചെയ്യാനുമാവും. പ്ലെയിൻടെക്സ്റ്റിൽ സ്ക്രീൻ ലോക്ക് സംഭരിക്കപ്പെട്ടിട്ടില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക, അതിനാൽ ആപ്പിന് കൃത്യമായ പാസ്വേഡ് അറിയില്ല."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ബയോമെട്രിക് ഹാർഡ്വെയർ ഉപയോഗിക്കുക"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"പരിശോധിച്ചുറപ്പിക്കുന്നതിനായി, ബയോമെട്രിക് ഹാർഡ്വെയർ ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ഫിംഗർപ്രിന്റ് ഹാർഡ്വെയർ നിയന്ത്രിക്കുക"</string> @@ -1083,23 +1087,23 @@ <string name="deleteText" msgid="6979668428458199034">"ഇല്ലാതാക്കുക"</string> <string name="inputMethod" msgid="1653630062304567879">"ടൈപ്പുചെയ്യൽ രീതി"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"ടെക്സ്റ്റ് പ്രവർത്തനങ്ങൾ"</string> - <string name="email" msgid="4560673117055050403">"ഇമെയിൽ"</string> + <string name="email" msgid="4560673117055050403">"ഇമെയിൽ അയയ്ക്കൂക"</string> <string name="email_desc" msgid="3638665569546416795">"തിരഞ്ഞെടുത്ത വിലാസത്തിലേക്ക് ഇമെയിൽ അയയ്ക്കുക"</string> <string name="dial" msgid="1253998302767701559">"വിളിക്കുക"</string> - <string name="dial_desc" msgid="6573723404985517250">"തിരഞ്ഞെടുത്ത നമ്പറിലേക്ക് കോൾ ചെയ്യുക"</string> - <string name="map" msgid="5441053548030107189">"മാപ്പ്"</string> + <string name="dial_desc" msgid="6573723404985517250">"തിരഞ്ഞെടുത്ത നമ്പറിലേക്ക് വിളിക്കുക"</string> + <string name="map" msgid="5441053548030107189">"മാപ്പ് തുറക്കുക"</string> <string name="map_desc" msgid="1836995341943772348">"തിരഞ്ഞെടുത്ത വിലാസം കണ്ടെത്തുക"</string> <string name="browse" msgid="1245903488306147205">"തുറക്കുക"</string> - <string name="browse_desc" msgid="8220976549618935044">"തിരഞ്ഞെടുത്ത URL ഓപ്പൺ ചെയ്യുക"</string> - <string name="sms" msgid="4560537514610063430">"സന്ദേശം"</string> + <string name="browse_desc" msgid="8220976549618935044">"തിരഞ്ഞെടുത്ത URL തുറക്കുക"</string> + <string name="sms" msgid="4560537514610063430">"സന്ദേശം അയയ്ക്കുക"</string> <string name="sms_desc" msgid="7526588350969638809">"തിരഞ്ഞെടുത്ത നമ്പറിലേക്ക് സന്ദേശം അയയ്ക്കുക"</string> <string name="add_contact" msgid="7867066569670597203">"ചേർക്കുക"</string> <string name="add_contact_desc" msgid="4830217847004590345">"കോൺടാക്റ്റുകളിലേക്ക് ചേർക്കുക"</string> <string name="view_calendar" msgid="979609872939597838">"കാണുക"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"കലണ്ടറിൽ തിരഞ്ഞെടുത്ത സമയം കാണുക"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"ഷെഡ്യൂള്"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"ഷെഡ്യൂള് ചെയ്യുക"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"തിരഞ്ഞെടുത്ത സമയത്തേക്ക് ഇവന്റ് ഷെഡ്യൂൾ ചെയ്യുക"</string> - <string name="view_flight" msgid="7691640491425680214">"ട്രാക്ക്"</string> + <string name="view_flight" msgid="7691640491425680214">"ട്രാക്ക് ചെയ്യുക"</string> <string name="view_flight_desc" msgid="3876322502674253506">"തിരഞ്ഞെടുത്ത ഫ്ലൈറ്റ് ട്രാക്ക് ചെയ്യുക"</string> <string name="translate" msgid="9218619809342576858">"വിവർത്തനം ചെയ്യുക"</string> <string name="translate_desc" msgid="4502367770068777202">"തിരഞ്ഞെടുത്ത ടെക്സ്റ്റ് വിവർത്തനം ചെയ്യുക"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ടാബ്ലെറ്റ് അപ്ഡേറ്റ് ചെയ്യുന്നു…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ഉപകരണം അപ്ഡേറ്റ് ചെയ്യുന്നു…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ഫോൺ ആരംഭിക്കുന്നു…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android ആരംഭിക്കുന്നു…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ടാബ്ലെറ്റ് ആരംഭിക്കുന്നു…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ഉപകരണം ആരംഭിക്കുന്നു…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"സ്റ്റോറേജ് ഒപ്റ്റിമൈസ് ചെയ്യുന്നു."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> നിർദേശിച്ച വൈഫൈ നെറ്റ്വർക്കിൽ കണക്റ്റ് ചെയ്തു"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"നിങ്ങൾക്കായി <xliff:g id="NAME">%s</xliff:g>-നെ നെറ്റ്വർക്കുകൾ നിർദ്ദേശിക്കാൻ അനുവദിക്കണോ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"നിങ്ങൾ ഉയർന്ന നിലവാരമുള്ള സംരക്ഷിക്കപ്പെട്ട നെറ്റ്വർക്കിനരികിലെത്തുമ്പോൾ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"തിരികെ ഓണാക്കരുത്"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 93f7e37480cf..c0b23fc8dd99 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Апп нь төхөөрөмжийн утасны функцд хандах боломжтой. Энэ зөвшөөрөл нь апп-д утасны дугаар болон төхөөрөмжийн ID-г, дуудлага идэвхтэй эсэх, холын дугаар дуудлагаар холбогдсон байгаа эсэхийг тогтоох боломжийг олгоно,"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"системээр дамжуулах дуудлага"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дуудлагыг сайжруулахын тулд дуудлагаа системээр дамжуулах зөвшөөрлийг апп-д олгодог."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"систем дэх дуудлагыг харах болон хянах."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Аппад төхөөрөмж дээр хийж буй дуудлагыг харах болон хянахыг зөвшөөрдөг. Үүнд дуудлагын дугаар болон дуудлагын төлөв зэрэг мэдээллийг агуулдаг."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"дуудлагыг өөр аппаас үргэлжлүүлэх"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Аппад өөр аппад эхлүүлсэн дуудлагыг үргэлжлүүлэхийг зөвшөөрдөг."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"утасны дугаарыг унших"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"дэлгэцийн түгжээний төвөгтэй байдлыг авах болон хүсэх"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Аппад дэлгэцийн түгжээний боломжит уртын хэмжээ болон төрлийг заадаг дэлгэцийн түгжээний төвөгтэй байдлын түвшнийг (өндөр, дундаж, бага эсвэл байхгүй) мэдэж авахыг зөвшөөрдөг. Түүнчлэн, апп хэрэглэгчдэд дэлгэцийн түгжээг тодорхой түвшинд шинэчлэхийг санал болгодог хэдий ч хэрэглэгч үүнийг чөлөөтэй үл хэрэгсэж, орхих боломжтой. Дэлгэцийн түгжээг ил бичвэрээр хадгалдаггүй тул апп тодорхой нууц үгийг мэддэггүй болохыг анхаарна уу."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"биометрийн техник хангамжийг ашиглах"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Aппад биометрийн техник хангамжийг баталгаажуулалтад ашиглахыг зөвшөөрдөг"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"хурууны хээний програм хангамжийг удирдах"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Таблетыг шинэчилж байна…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Төхөөрөмжийг шинэчилж байна…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Утсыг эхлүүлж байна…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Андройд эхэлж байна..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Таблетыг эхлүүлж байна…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Төхөөрөмжийг эхлүүлж байна…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Хадгалалтыг сайжруулж байна."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g>-с санал болгосон Wi-Fi сүлжээнд холбогдсон"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Та <xliff:g id="NAME">%s</xliff:g>-г танд сүлжээ санал болгохыг хүсэж байна уу?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Таныг хадгалсан, өндөр чанартай сүлжээний ойролцоо байх үед"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Буцааж асаахгүй"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 902380b6696f..f3d6b4ba5db5 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -317,18 +317,18 @@ <string name="permgrouplab_visual" msgid="8030190588123857921">"फोटो आणि व्हिडिओ"</string> <string name="permgroupdesc_visual" msgid="3415827902566663546">"तुमचे फोटो आणि व्हिडिओ अॅक्सेस करा"</string> <string name="permgrouprequest_visual" msgid="6907523945030290376">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला तुमचे फोटो आणि व्हिडिओ अॅक्सेस करू द्यायचे का?"</string> - <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री पुनर्प्राप्त करा"</string> - <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तुम्ही परस्परसंवाद करीत असलेल्या विंडोची सामग्री तपासा."</string> + <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडोमधील आशय पुन्हा मिळवा"</string> + <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तुम्ही वापरत असलेल्या विंडोमधील आशय तपासा."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श करून अन्वेषण चालू करा"</string> <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"टॅप केलेले आयटम मोठ्याने बोलले जातील आणि जेश्चरचा वापर करून स्क्रीन एक्सप्लोर केली जाऊ शकते."</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"तुम्ही टाइप करता त्या मजकुराचे निरीक्षण करा"</string> - <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"क्रेडिट कार्ड नंबर आणि संकेतशब्द यासारखा वैयक्तिक डेटा समाविष्ट करते."</string> - <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"डिस्प्ले मॅग्निफिकेशन नियंत्रित करा"</string> - <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शनाचा झूम स्तर आणि स्थिती निर्धारण नियंत्रित करा."</string> + <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"यामध्ये क्रेडिट कार्ड नंबर आणि पासवर्ड यासारखा वैयक्तिक डेटा समाविष्ट आहे."</string> + <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"डिस्प्ले मोठा करण्यावर नियंत्रण ठेवा"</string> + <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"डिस्प्लेची झूम पातळी आणि पोझिशनिंग नियंत्रित करा."</string> <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"जेश्चर करा"</string> <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"टॅप, स्वाइप, पिंच आणि इतर जेश्चर करू शकते."</string> <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फिंगरप्रिंट जेश्चर"</string> - <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"डिव्हाइसच्या फिंगरप्रिंट सेंसरवर केलेले जेश्चर कॅप्चर करू शकते."</string> + <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"डिव्हाइसच्या फिंगरप्रिंट सेंन्सरवरील जेश्चर कॅप्चर करू शकते."</string> <string name="permlab_statusBar" msgid="7417192629601890791">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string> <string name="permdesc_statusBar" msgid="8434669549504290975">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अॅप ला अनुमती देते."</string> <string name="permlab_statusBarService" msgid="4826835508226139688">"स्टेटस बार होऊ द्या"</string> @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"डिव्हाइस च्या फोन वैशिष्ट्यांवर अॅक्सेस करण्यास अॅपला अनुमती देते. ही परवानगी कॉल अॅक्टिव्हेट असला किंवा नसला तरीही, फोन नंबर आणि डिव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रिमोट नंबर निर्धारित करण्यासाठी अॅपला अनुमती देते."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"प्रणालीच्या माध्यमातून कॉल रूट करा"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करण्याचा अनुभव सुधारण्यासाठी अॅपला त्याचे कॉल प्रणालीच्या माध्यमातून रूट करू देते."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"सिस्टम वापरून कॉल पाहा आणि नियंत्रण ठेवा."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"डिव्हाइसवर येणार कॉल पाहण्यासाठी आणि नियंत्रित करण्यासाठी अॅपला अनुमती देते. यामध्ये कॉल करण्यासाठी कॉलचा नंबर आणि कॉलची स्थिती यासारख्या माहितीचा समावेश असतो."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"दुसऱ्या अॅपवरून कॉल करणे सुरू ठेवा"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"दुसऱ्या अॅपमध्ये सुरू झालेल्या कॉलला पुढे सुरू ठेवण्याची अॅपला अनुमती देते."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फोन नंबर वाचा"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"स्क्रीन लॉक जटिलता मिळवा आणि त्यासाठी विनंती करा"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"अॅपला स्क्रीन लॉक जटिलता पातळी (उच्च, मध्यम, खालची किंवा काहीही नाही) जाणून घेऊ देते, जी लांबीची संभाव्य श्रेणी आणि स्क्रीन लॉकचा प्रकार सूचित करते. अॅप वापरकर्त्यांना हेदेखील सुचवू शकते की त्यांनी स्क्रीन लॉक ठराविक पातळीपर्यंत अपडेट करावे परंतु वापरकर्ते मुक्तपणे ते दुर्लक्षित करू शकतात आणि तेथून नेव्हिगेट करू शकतात. स्क्रीन लॉक प्लेनटेक्स्टमध्ये स्टोअर केले जात नसल्यामुळे अॅपला नेमका पासवर्ड माहीत नसतो याची नोंद घ्या."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"बायोमेट्रिक हार्डवेअर वापरा"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ऑथेंटिकेशनसाठी बायोमेट्रिक हार्डवेअरचा वापर करण्याची अॅपला अनुमती देते"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"फिंगरप्रिंट हार्डवेअर व्यवस्थापित करा"</string> @@ -1110,7 +1114,7 @@ <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टीमसाठी पुरेसे संचयन नाही. आपल्याकडे 250MB मोकळे स्थान असल्याचे सुनिश्चित करा आणि रीस्टार्ट करा."</string> <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> चालत आहे"</string> <string name="app_running_notification_text" msgid="1197581823314971177">"अधिक माहितीसाठी किंवा अॅप थांबविण्यासाठी टॅप करा."</string> - <string name="ok" msgid="5970060430562524910">"ठीक"</string> + <string name="ok" msgid="5970060430562524910">"ठीक आहे"</string> <string name="cancel" msgid="6442560571259935130">"रद्द करा"</string> <string name="yes" msgid="5362982303337969312">"ठीक"</string> <string name="no" msgid="5141531044935541497">"रद्द करा"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"टॅबलेट अपडेट होत आहे…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"डिव्हाइस अपडेट होत आहे…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"फोन सुरू होत आहे…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android प्रारंभ करत आहे…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"टॅबलेट सुरू होत आहे…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"डिव्हाइस सुरू होत आहे…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"संचयन ऑप्टिमाइझ करत आहे."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> ने सुचवलेल्या वाय-फाय नेटवर्कशी कनेक्ट केले"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"तुम्हाला <xliff:g id="NAME">%s</xliff:g> ने तुमच्यासाठी नेटवर्क सुचवायला हवे आहे का?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"तुम्ही जेव्हा सेव्ह केलेल्या उच्च दर्जाच्या नेटवर्कजवळ असाल तेव्हा"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"पुन्हा चालू करू नका"</string> @@ -1857,7 +1866,7 @@ <string name="language_selection_title" msgid="2680677278159281088">"एक भाषा जोडा"</string> <string name="country_selection_title" msgid="2954859441620215513">"प्रदेश प्राधान्य"</string> <string name="search_language_hint" msgid="7042102592055108574">"भाषा नाव टाइप करा"</string> - <string name="language_picker_section_suggested" msgid="8414489646861640885">"सूचित केलेले"</string> + <string name="language_picker_section_suggested" msgid="8414489646861640885">"सुचवलेल्या भाषा"</string> <string name="language_picker_section_all" msgid="3097279199511617537">"सर्व भाषा"</string> <string name="region_picker_section_all" msgid="8966316787153001779">"सर्व प्रदेश"</string> <string name="locale_search_menu" msgid="2560710726687249178">"शोध"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 6492f48d2f46..0eb022a4a1c0 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Membenarkan apl mengakses ciri telefon pada peranti. Kebenaran ini membolehkan apl menentukan nombor telefon dan ID peranti, sama ada panggilan aktif dan nombor jauh yang dihubungkan dengan panggilan."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"halakan panggilan menerusi sistem"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Membenarkan apl menghalakan panggilan menerusi sistem untuk meningkatkan pengalaman panggilan."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"lihat dan kawal panggilan melalui sistem."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Membenarkan apl melihat dan mengawal panggilan yang sedang berlangsung pada peranti. Ini termasuklah maklumat seperti nombor panggilan untuk panggilan dan keadaan panggilan tersebut."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"teruskan panggilan daripada apl lain"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Membenarkan apl meneruskan panggilan yang dimulakan dalam apl lain."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"baca nombor telefon"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Membenarkan apl berkomunikasi dengan teg, kad dan pembaca Komunikasi Medan Dekat (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"lumpuhkan kunci skrin anda"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Membenarkan apl melumpuhkan kunci kekunci dan sebarang keselamatan kata laluan yang berkaitan. Sebagai contoh, telefon melumpuhkan kunci kekunci apabila menerima panggilan telefon masuk kemudian mendayakan semula kunci kekunci apabila panggilan selesai."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"dapatkan dan minta kekompleksan kunci skrin"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Benarkan apl mengetahui tahap kekompleksan kunci skrin (tinggi, sederhana, rendah atau tiada) yang menunjukkan kemungkinan julat panjang dan jenis kunci skrin. Apl juga boleh mencadangkan kepada pengguna supaya mengemas kini kunci skrin pada tahap tertentu namun pengguna boleh mengabaikan dan menavigasi keluar dengan bebas. Sila ambil perhatian bahawa kunci skrin tidak disimpan dalam teks biasa, maka apl tidak mengetahui kata laluan yang tepat."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"gunakan perkakasan biometrik"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Membenarkan apl menggunakan perkakasan biometrik untuk pengesahan"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"urus perkakasan cap jari"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet sedang mengemas kini…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Peranti sedang mengemas kini…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon sedang dimulakan…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android sedang dimulakan…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet sedang dimulakan…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Peranti sedang dimulakan…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Mengoptimumkan storan."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua rangkaian"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Dihubungkan ke rangkaian Wi‑Fi yang dicadangkan oleh <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Adakah anda ingin <xliff:g id="NAME">%s</xliff:g> mencadangkan rangkaian kepada anda?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan dihidupkan secara automatik"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Apabila anda berada berdekatan dengan rangkaian disimpan yang berkualiti tinggi"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Jangan hidupkan kembali"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index a3da75ea0ed3..1c5f0c716a2f 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"အပလီကေးရှင်းအား ဖုန်းရဲ့ စွမ်းဆောင်ချက်များအား သုံးခွင့်ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် ဖုန်းနံပါတ်၊ စက်နံပါတ်၊ ဖုန်းခေါ်နေမှု ရှိမရှိနှင့် တဖက်မှ ဖုန်းနံပါတ် များအား သိရှိနိုင်ပါသည်"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ခေါ်ဆိုမှုများကို စနစ်မှတစ်ဆင့် ဖြတ်သန်းခွင့်ပြုပါ"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"ခေါ်ဆိုမှု အတွေ့အကြုံ ပိုမိုကောင်းမွန်လာစေရန်အတွက် အက်ပ်၏ ခေါ်ဆိုမှုအား စနစ်မှတစ်ဆင့် ဖြတ်သန်းရန် ခွင့်ပြုပါသည်။"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"စနစ်မှတစ်ဆင့် ခေါ်ဆိုမှုများကို ကြည့်ရှုထိန်းချုပ်ပါ။"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"စက်ပစ္စည်းပေါ်ရှိ လက်ရှိခေါ်ဆိုမှုများကို အက်ပ်အား ကြည့်ရှုထိန်းချုပ်ခွင့်ပြုသည်။ ၎င်းတွင် ခေါ်ဆိုမှုနံပါတ်များနှင့် ခေါ်ဆိုမှုအခြေအနေများကဲ့သို့သော အခြေအနေများ ပါဝင်သည်။"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"အခြားအက်ပ်မှ ဖုန်းခေါ်ဆိုမှုကို ဆက်လက်ပြုလုပ်ပါ"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"အခြားအက်ပ်တွင် စတင်ထားသည့် ဖုန်းခေါ်ဆိုမှုကို ဆက်လက်ပြုလုပ်ရန် ဤအက်ပ်ကို ခွင့်ပြုသည်။"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ဖုန်းနံပါတ်များကို ဖတ်ရန်"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ဖုန်းမျက်နှာပြင်လော့ခ် ရှုပ်ထွေးမှုကို ရယူခြင်းနှင့် တောင်းခံခြင်း"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ဖုန်းမျက်နှာပြင်လော့ခ်၏ ရှုပ်ထွေးမှုအဆင့် (မြင့်၊ အလယ်အလတ်၊ နိမ့် သို့မဟုတ် မရှိ) အား လေ့လာရန် အက်ပ်ကို ခွင့်ပြုသည်။ ၎င်းက သတ်မှတ်ထားနိုင်သော ဖုန်းမျက်နှာပြင်လော့ခ်၏ စာလုံးရေနှင့် အမျိုးအစားကို ညွှန်ပြပေးသည်။ အသုံးပြုသူများအနေနှင့် ဖုန်းမျက်နှာပြင်လော့ခ်ကို အတိုင်းအတာတစ်ခုအထိ အဆင့်မြှင့်ရန် အက်ပ်က အကြံပြုနိုင်သည်။ သို့သော်လည်း အသုံးပြုသူများက ၎င်းကို ဂရုပြုမနေဘဲ လွတ်လပ်စွာ ကြည့်ရှုနိုင်ပါသည်။ ဖုန်းမျက်နှာပြင်လော့ခ်ကို စာသားအတိုင်း သိမ်းမထားသဖြင့် အက်ပ်သည် စကားဝှက်အစစ်ကို မသိနိုင်ကြောင်း သတိပြုပါ။"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ဇီဝဗေဒဆိုင်ရာ အချက်အလက်သုံး ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန်"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"အထောက်အထားစိစစ်ခြင်းအတွက် ဇီဝဗေဒဆိုင်ရာ သတင်းအချက်အလက်များသုံးသည့် ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"လက်ဗွေရာပစ္စည်းကို စီမံမည်"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"တက်ဘလက်ကို အပ်ဒိတ်လုပ်နေသည်…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"စက်ပစ္စည်းကို အပ်ဒိတ်လုပ်နေသည်…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ဖုန်း စတင်နေသည်…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android စတင်နေ…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"တက်ဘလက် စတင်နေသည်…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"စက်ပစ္စည်း စတင်နေသည်…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"သိုလှောင်မှုအား ပြုပြင်ခြင်း။"</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> အကြံပြုထားသော Wi‑Fi ကွန် ရက်သို့ ချိတ်ဆက်ထားသည်"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"သင့်အတွက် ကွန်ရက်များ အကြံပြုရန် <xliff:g id="NAME">%s</xliff:g> ကို ခွင့်ပြုလိုပါသလား။"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ကို အလိုအလျောက် ပြန်ဖွင့်ပေးလိမ့်ပါမည်"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"သိမ်းဆည်းထားသည့် အရည်အသွေးမြင့်ကွန်ရက်များအနီးသို့ ရောက်ရှိသည့်အခါ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ပြန်မဖွင့်ပါနှင့်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 30cd600f734b..233b98a614b1 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lar appen bruke enhetens telefonfunksjoner. Med denne tillatelsen kan appen finne telefonnummer og enhets-ID-er, registrere om en samtale pågår, og se det eksterne nummeret det opprettes en forbindelse med via oppringing."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"send anrop gjennom systemet"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Lar appen sende anrop gjennom systemet for å forbedre anropsopplevelsen."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"se og kontrollere anrop i systemet."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Lar appen se og kontrollere anrop som pågår på enheten. Dette inkluderer informasjon som anropsnumre og tilstanden til anropene."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"fortsette et anrop fra en annen app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Lar appen fortsette et anrop som ble startet i en annen app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"les telefonnumre"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Lar appen kommunisere med etiketter, kort og lesere som benytter NFC-teknologi."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivere skjermlåsen"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lar appen deaktivere tastelåsen og eventuell tilknyttet passordsikkerhet. Et eksempel er at telefonen deaktiverer tastelåsen når du mottar et innkommende anrop, og deretter aktiverer tastelåsen igjen når samtalen er ferdig."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"hente og be om kompleksitet for skjermlås"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Lar appen lære skjermlåsens kompleksitetsnivå (høy, middels, lav eller ingen), som indikerer det mulige området for lengde og type skjermlås. Appen kan foreslå at brukeren oppdaterer skjermlåsen til et bestemt nivå, men brukere kan velge å ignorere dette og navigere bort. Vær oppmerksom på at skjermlåsen ikke er lagret klartekst, så appen kan ikke se det nøyaktige passordet."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"bruke biometrisk maskinvare"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Lar appen bruke biometrisk maskinvare til godkjenning"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"administrere fingeravtrykkmaskinvare"</string> @@ -1083,21 +1087,21 @@ <string name="deleteText" msgid="6979668428458199034">"Slett"</string> <string name="inputMethod" msgid="1653630062304567879">"Inndatametode"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string> - <string name="email" msgid="4560673117055050403">"E-post"</string> + <string name="email" msgid="4560673117055050403">"Send e-post"</string> <string name="email_desc" msgid="3638665569546416795">"Send e-post til den valgte adressen"</string> <string name="dial" msgid="1253998302767701559">"Ring"</string> <string name="dial_desc" msgid="6573723404985517250">"Ring det valgte telefonnummeret"</string> - <string name="map" msgid="5441053548030107189">"Kart"</string> + <string name="map" msgid="5441053548030107189">"Se Kart"</string> <string name="map_desc" msgid="1836995341943772348">"Finn den valgte adressen"</string> <string name="browse" msgid="1245903488306147205">"Åpne"</string> <string name="browse_desc" msgid="8220976549618935044">"Åpne den valgte nettadressen"</string> - <string name="sms" msgid="4560537514610063430">"Melding"</string> + <string name="sms" msgid="4560537514610063430">"Send melding"</string> <string name="sms_desc" msgid="7526588350969638809">"Send melding til det valgte telefonnummeret"</string> <string name="add_contact" msgid="7867066569670597203">"Legg til"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Legg til i kontakter"</string> <string name="view_calendar" msgid="979609872939597838">"Se"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Se det valgte klokkeslettet i kalenderen"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Oversikt"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Planlegg"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Planlegg aktivitet for valgt klokkeslett"</string> <string name="view_flight" msgid="7691640491425680214">"Spor"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Spor den valgte flyvningen"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Nettbrettet oppdateres …"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Enheten oppdateres …"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefonen starter …"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android starter …"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Nettbrettet starter …"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Enheten starter …"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimaliser lagring."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle nettverk"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Koblet til et Wi-Fi-nettverk som ble foreslått av <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Vil du la <xliff:g id="NAME">%s</xliff:g> foreslå nettverk for deg?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi slås på automatisk"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Når du er i nærheten av et lagret nettverk av høy kvalitet"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ikke slå på igjen"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 188ce8bd3320..0b2362ae405d 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"उपकरणको फोन विशेषताहरूको पहुँच गर्न अनुप्रयोगलाई अनुमति दिन्छ। यस अनुमतिले फोन नम्बर र उपकरणको IDs, कल सक्षम छ कि छैन र कलद्वारा जोडिएको टाढाको नम्बर निर्धारण गर्न अनुमति दिन्छ।"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"प्रणाली मार्फत कल गर्न दिनुहोस्"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कल गर्दाको अनुभवलाई सुधार्न यस अनुप्रयोगलाई प्रणाली मार्फत कलहरू गर्न अनुमति दिन्छ।"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"प्रणालीमार्फत कलहरू हेर्नुका साथै तिनीहरूलाई नियन्त्रण गर्नुहोस्।"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"अनुप्रयोगलाई यन्त्रमा जारी रहेका कलहरू हेर्नुका साथै तिनीहरूलाई गर्ने अनुमति दिनुहोस्। यसमा गरिएका कलहरूको सङ्ख्या र कलहरूको अवस्था जस्ता जानकारी समावेश हुन्छन्।"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"अर्को अनुप्रयोगमा सुरु गरिएको कल जारी राख्नुहोस्"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"यस अनुप्रयोगलाई अर्को अनुप्रयोगमा सुरु गरिएको कल जारी राख्ने अनुमति दिन्छ।"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फोन नम्बरहरू पढ्ने"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"स्क्रिन लकको जटिलतासम्बन्धी जानकारी प्राप्त गर्न र त्यसका लागि अनुरोध गर्न"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"यसले अनुप्रयोगलाई स्क्रिन लकको जटिलताको स्तर (उच्च, मध्यम, न्यून वा कुनै पनि होइन) थाहा पाउने अनुमति दिन्छ जसले स्क्रिन लकको लम्बाइको सम्भावित दायरा र त्यसको प्रकारलाई जनाउँछ। यसै गरी, यो अनुप्रयोगले प्रयोगकर्ताहरूलाई स्क्रिन लक अद्यावधिक गर्ने सुझाव पनि दिन सक्छ तर प्रयोगकर्ताहरू उक्त सुझावको बेवास्ता गरी बाहिर निस्कन सक्छन्। स्क्रिन लकलाई सादा पाठको ढाँचामा भण्डारण नगरिने हुँदा यो अनुप्रयोगले वास्तविक पासवर्ड थाहा पाउँदैन भन्ने कुरा याद राख्नुहोस्।"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"बायोमेट्रिक हार्डवेयर प्रयोग गर्नुहोस्"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"अनुप्रयोगलाई प्रमाणीकरणका लागि बायोमेट्रिक हार्डवेयर प्रयोग गर्न अनुमति दिन्छ"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"औठाछाप हार्डवेयर व्यवस्थापन गर्नुहोस्"</string> @@ -1083,28 +1087,28 @@ <string name="deleteText" msgid="6979668428458199034">"मेट्नुहोस्"</string> <string name="inputMethod" msgid="1653630062304567879">"निवेश विधि"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ कार्यहरू"</string> - <string name="email" msgid="4560673117055050403">"इमेल"</string> + <string name="email" msgid="4560673117055050403">"इमेल गर्नुहोस्"</string> <string name="email_desc" msgid="3638665569546416795">"चयन गरिएको ठेगानामा इमेल पठाउनुहोस्"</string> - <string name="dial" msgid="1253998302767701559">"कल"</string> + <string name="dial" msgid="1253998302767701559">"कल गर्नुहोस्"</string> <string name="dial_desc" msgid="6573723404985517250">"चयन गरिएको फोन नम्बरमा कल गर्नुहोस्"</string> - <string name="map" msgid="5441053548030107189">"नक्सा"</string> + <string name="map" msgid="5441053548030107189">"नक्सा अनुप्रयोग खोल्नुहोस्"</string> <string name="map_desc" msgid="1836995341943772348">"चयन गरिएको ठेगाना पत्ता लगाउनुहोस्"</string> <string name="browse" msgid="1245903488306147205">"खोल्नुहोस्"</string> <string name="browse_desc" msgid="8220976549618935044">"चयन गरिएको URL खोल्नुहोस्"</string> - <string name="sms" msgid="4560537514610063430">"सन्देश"</string> + <string name="sms" msgid="4560537514610063430">"सन्देश पठाउनुहोस्"</string> <string name="sms_desc" msgid="7526588350969638809">"चयन गरिएको फोन नम्बरमा सन्देश पठाउनुहोस्"</string> <string name="add_contact" msgid="7867066569670597203">"थप्नुहोस्"</string> <string name="add_contact_desc" msgid="4830217847004590345">"सम्पर्क सूचीमा थप्नुहोस्"</string> <string name="view_calendar" msgid="979609872939597838">"हेर्नुहोस्"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"पात्रोमा चयन गरिएको समय हेर्नुहोस्"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"समयतालिका"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"समयतालिका बनाउनुहोस्"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"चयन गरिएको समयका लागि कार्यक्रमको समयतालिका बनाउनुहोस्"</string> <string name="view_flight" msgid="7691640491425680214">"ट्र्याक गर्नुहोस्"</string> <string name="view_flight_desc" msgid="3876322502674253506">"चयन गरिएको उडान ट्रयाक गर्नुहोस्"</string> <string name="translate" msgid="9218619809342576858">"अनुवाद गर्नुहोस्"</string> - <string name="translate_desc" msgid="4502367770068777202">"चयन गरिएको पाठ अनुवाद गर्नुहोस्"</string> - <string name="define" msgid="7394820043869954211">"परिभाषा गर्नुहोस्"</string> - <string name="define_desc" msgid="7910883642444919726">"चयन गरिएको पाठ परिभाषा गर्नुहोस्"</string> + <string name="translate_desc" msgid="4502367770068777202">"चयन गरिएको पाठको अनुवाद गर्नुहोस्"</string> + <string name="define" msgid="7394820043869954211">"परिभाषा दिनुहोस्"</string> + <string name="define_desc" msgid="7910883642444919726">"चयन गरिएको पाठको परिभाषा दिनुहोस्"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"भण्डारण ठाउँ सकिँदै छ"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"सायद केही प्रणाली कार्यक्रमहरूले काम गर्दैनन्"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"प्रणालीको लागि पर्याप्त भण्डारण छैन। तपाईँसँग २५० मेगा बाइट ठाउँ खाली भएको निश्चित गर्नुहोस् र फेरि सुरु गर्नुहोस्।"</string> @@ -1187,6 +1191,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ट्याब्लेटको अद्यावधिक गरिँदै छ…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"यन्त्रको अद्यावधिक गरिँदै छ…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"फोन सुरु हुँदै छ…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android शुरू हुँदैछ..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ट्याब्लेट सुरु हुँदै छ…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"यन्त्र सुरु हुँदै छ…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"भण्डारण आफू अनुकूल गर्दै।"</string> @@ -1245,6 +1250,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> ले प्रस्ताव गरेको Wi‑Fi नेटवर्कमा जोडियो"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"तपाईं <xliff:g id="NAME">%s</xliff:g> लाई आफ्ना लागि नेटवर्कहरूको प्रस्ताव गर्ने अनुमति दिन चाहनुहुन्छ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"तपाईं कुनै सुरक्षित गरिएको उच्च गुणस्तरीय नेटवर्कको नजिक हुनुभएको अवस्थामा"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"फेरि सक्रिय नगर्नुहोला"</string> @@ -1743,7 +1752,7 @@ <string name="reason_service_unavailable" msgid="7824008732243903268">"प्रिन्ट सेवा सक्षम गरिएको छैन"</string> <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> सेवा स्थापित भयो"</string> <string name="print_service_installed_message" msgid="5897362931070459152">"सक्षम पार्न ट्याप गर्नुहोस्"</string> - <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"प्रशासकको PIN प्रविष्ट गर्नुहोस्"</string> + <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"प्रशासकको PIN प्रविष्टि गर्नुहोस्"</string> <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN प्रविष्टि गर्नुहोस्"</string> <string name="restr_pin_incorrect" msgid="8571512003955077924">"गलत"</string> <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"वर्तमान PIN"</string> @@ -1905,7 +1914,7 @@ <string name="time_picker_hour_label" msgid="2979075098868106450">"घन्टा"</string> <string name="time_picker_minute_label" msgid="5168864173796598399">"मिनेट"</string> <string name="time_picker_header_text" msgid="143536825321922567">"समय सेट गर्नुहोस्"</string> - <string name="time_picker_input_error" msgid="7574999942502513765">"मान्य समय प्रविष्ट गर्नुहोस्"</string> + <string name="time_picker_input_error" msgid="7574999942502513765">"मान्य समय प्रविष्टि गर्नुहोस्"</string> <string name="time_picker_prompt_label" msgid="7588093983899966783">"समय टाइप गर्नुहोस्"</string> <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"समय इनपुट गर्न पाठ इनपुट मोडमा स्विच गर्नुहोस्।"</string> <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"समय इनपुट गर्न घडी मोडमा स्विच गर्नुहोस्।"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 2ff9fde39b49..996b700d5a33 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Hiermee kan de app toegang krijgen tot de telefoonfuncties van het apparaat, Met deze toestemming kan de app het telefoonnummer en de apparaat-ID\'s bepalen, of een gesprek actief is, en het andere telefoonnummer waarmee wordt gebeld."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"gesprekken doorschakelen via het systeem"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Hiermee kan de app de bijbehorende gesprekken doorschakelen via het systeem om de belfunctionaliteit te verbeteren."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"gesprekken via het systeem bekijken en beheren"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Hiermee kan de app actieve gesprekken op het apparaat bekijken en beheren. Dit omvat informatie zoals nummers voor gesprekken en de status van de gesprekken."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"een gesprek voortzetten vanuit een andere app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Hiermee kan de app een gesprek voortzetten dat is gestart in een andere app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"telefoonnummers lezen"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Hiermee kan de app communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"je schermvergrendeling uitschakelen"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Hiermee kan de app de toetsenblokkering en bijbehorende wachtwoordbeveiliging uitschakelen. Zo kan de telefoon de toetsenblokkering uitschakelen wanneer je wordt gebeld en de toetsenblokkering weer inschakelen als het gesprek is beëindigd."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"complexiteit van schermbeveiliging ophalen en aanvragen"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Hiermee krijgt de app toestemming om het complexiteitsniveau van de schermvergrendeling te achterhalen (hoog, midden, laag of geen). Dat geeft een indicatie van het mogelijke lengtebereik en type van de schermvergrendeling. De app kan gebruikers ook voorstellen de schermvergrendeling naar een bepaald niveau te updaten, maar gebruikers kunnen dit altijd negeren en de app verlaten. De schermvergrendeling wordt niet opgeslagen in platte tekst, zodat de app het precieze wachtwoord niet weet."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrische hardware gebruiken"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Hiermee kan de app biometrische hardware gebruiken voor verificatie"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Vingerafdrukhardware beheren"</string> @@ -1083,15 +1087,15 @@ <string name="deleteText" msgid="6979668428458199034">"Verwijderen"</string> <string name="inputMethod" msgid="1653630062304567879">"Invoermethode"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string> - <string name="email" msgid="4560673117055050403">"E-mail"</string> + <string name="email" msgid="4560673117055050403">"E-mailen"</string> <string name="email_desc" msgid="3638665569546416795">"E-mail sturen aan geselecteerd e-mailadres"</string> <string name="dial" msgid="1253998302767701559">"Bellen"</string> <string name="dial_desc" msgid="6573723404985517250">"Geselecteerd telefoonnummer bellen"</string> - <string name="map" msgid="5441053548030107189">"Kaart"</string> + <string name="map" msgid="5441053548030107189">"Kaart openen"</string> <string name="map_desc" msgid="1836995341943772348">"Geselecteerd adres zoeken"</string> <string name="browse" msgid="1245903488306147205">"Openen"</string> <string name="browse_desc" msgid="8220976549618935044">"Geselecteerde URL openen"</string> - <string name="sms" msgid="4560537514610063430">"Bericht"</string> + <string name="sms" msgid="4560537514610063430">"Bericht verzenden"</string> <string name="sms_desc" msgid="7526588350969638809">"Sms sturen aan geselecteerd telefoonnummer"</string> <string name="add_contact" msgid="7867066569670597203">"Toevoegen"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Toevoegen aan contacten"</string> @@ -1100,7 +1104,7 @@ <string name="add_calendar_event" msgid="1953664627192056206">"Plannen"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Evenement plannen voor geselecteerde tijd"</string> <string name="view_flight" msgid="7691640491425680214">"Volgen"</string> - <string name="view_flight_desc" msgid="3876322502674253506">"Geselecteerde vlucht tonen"</string> + <string name="view_flight_desc" msgid="3876322502674253506">"Geselecteerde vlucht volgen"</string> <string name="translate" msgid="9218619809342576858">"Vertalen"</string> <string name="translate_desc" msgid="4502367770068777202">"Geselecteerde tekst vertalen"</string> <string name="define" msgid="7394820043869954211">"Definiëren"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet wordt geüpdatet…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Apparaat wordt geüpdatet…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefoon wordt gestart…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android wordt gestart…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet wordt gestart…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Apparaat wordt gestart…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Opslagruimte wordt geoptimaliseerd."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerken"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Verbonden met wifi-netwerk dat is voorgesteld door <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Wil je dat <xliff:g id="NAME">%s</xliff:g> je netwerken kan voorstellen?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wifi wordt automatisch ingeschakeld"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wanneer je in de buurt van een opgeslagen netwerk van hoge kwaliteit bent"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Niet weer inschakelen"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index f1c7bafd93e4..27b7d5dca164 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ଆପ୍କୁ ଡିଭାଇସ୍ର ଫୋନ୍ ବୈଶିଷ୍ଟ୍ୟ ଆକ୍ସେସ୍ କରିବାକୁ ଅନୁମତି ଦେଇଥାଏ। ଏହି ଅନୁମତି ଆପ୍କୁ ଫୋନ୍ ନମ୍ବର୍ ଓ ଡିଭାଇସ୍ IDଗୁଡ଼ିକୁ ନିର୍ଦ୍ଧାରଣ କରିବାକୁ ଅନୁମତି ଦେଇଥାଏ, କଲ୍ ସକ୍ରିୟ ଥିଲେ ବି ଏବଂ କଲ୍ ଦ୍ୱାରା ସଂଯୋଗ ଥିବା ରିମୋଟ୍ ନମ୍ବର୍କୁ ମଧ୍ୟ।"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ସିଷ୍ଟମ୍ ଜରିଆରେ କଲ୍ର ମାର୍ଗ ବଦଳାଇପାରେ"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"କଲ୍ କରିବାର ଅନୁଭୂତି ବଢ଼ାଇବାକୁ ସିଷ୍ଟମ୍ ଜରିଆରେ ଆପର କଲ୍ଗୁଡ଼ିକୁ ରୁଟ୍ କରିବାକୁ ଏହାକୁ ଅନୁମତି ଦେଇଥାଏ।"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ସିଷ୍ଟମ୍ ମାଧ୍ୟମରେ କଲ୍ଗୁଡ଼ିକୁ ଦେଖିଥାଏ ଏବଂ ନିୟନ୍ତ୍ରଣ କରିଥାଏ।"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ଆପ୍କୁ ଡିଭାଇସ୍ରେ ଚାଲୁଥିବା କଲ୍ଗୁଡ଼ିକୁ ଦେଖିବାକୁ ଏବଂ ନିୟନ୍ତ୍ରଣ କରିବାକୁ ଅନୁମତି ଦେଇଥାଏ। ଏଥିରେ କଲ୍ଗୁଡ଼ିକ ପାଇଁ କଲ୍ ନମ୍ବର୍ ଏବଂ କଲ୍ଗୁଡ଼ିକର ସ୍ଥିତି ପରି ସୂଚନା ଅନ୍ତର୍ଭୁକ୍ତ ଅଛି।"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ଅନ୍ୟ ଏକ ଆପ୍ରୁ କଲ୍କୁ ଜାରି ରଖନ୍ତୁ"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"ଅନ୍ୟ ଆପ୍ରେ ଆରମ୍ଭ ହୋଇଥିବା ଗୋଟିଏ କଲ୍କୁ ଜାରି ରଖିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦିଅନ୍ତୁ।"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ଫୋନ୍ ନମ୍ବର ପଢ଼େ"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ସ୍କ୍ରିନ୍ ଲକ୍ର ଜଟିଳତା ପ୍ରାପ୍ତ କରନ୍ତୁ କିମ୍ବା ଅନୁରୋଧ କରନ୍ତୁ"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ସ୍କ୍ରିନ୍ ଲକ୍ର ଜଟିଳତା ସ୍ତର (ଉଚ୍ଚ, ମଧ୍ୟମ, ନିମ୍ନ କିମ୍ବା କିଛିନୁହେଁ), ଜାଣିବାକୁ ଆପ୍କୁ ଅନୁମତି ଦିଅନ୍ତୁ, ଯାହା ସ୍କ୍ରିନ୍ ଲକ୍ର ସମ୍ଭାବ୍ୟ ପରିସୀମାର ଲମ୍ବ ଏବଂ ପ୍ରକାର ସୂଚୀତ କରେ। ଆପ୍ ଏହା ମଧ୍ୟ ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରାମର୍ଶ ଦେଇପାରେ ଯେ ସେମାନେ ସ୍କ୍ରିନ୍ ଲକ୍କୁ ଏକ ନିର୍ଦ୍ଧିଷ୍ଟ ସ୍ତର ପର୍ଯ୍ୟନ୍ତ ଅପ୍ଡେଟ୍ କରିପାରନ୍ତି, କିନ୍ତୁ ଉପଯୋଗକର୍ତ୍ତାମାନେ ନିଜ ଇଚ୍ଛାରେ ଏହାକୁ ଉପେକ୍ଷା ଏବଂ ନାଭିଗେଟ୍ କରିପାରିବେ। ଏହା ଧ୍ୟାନ ଦିଅନ୍ତୁ ଯେ ସ୍କ୍ରିନ୍ ଲକ୍ ସରଳ ଟେକ୍ସଟ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇନଥାଏ ଯେପରି ଆପ୍ ସଠିକ୍ ପାସ୍ୱର୍ଡ ଜାଣିପାରିନଥାଏ।"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ବାୟୋମେଟ୍ରିକ୍ ହାର୍ଡୱେର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ସ୍ୱୀକୃତି ପାଇଁ ବାୟୋମେଟ୍ରିକ୍ ହାର୍ଡୱେର୍ ବ୍ୟବହାର କରିବାକୁ ଅନୁମତି ଦିଏ"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ହାର୍ଡୱେର୍ ପରିଚାଳନା କରନ୍ତୁ"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ଟାବଲେଟ୍ ଅପଡେଟ୍ ହେଉଛି…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ଡିଭାଇସ୍ ଅପଡେଟ୍ ହେଉଛି…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ଫୋନ୍ ଆରମ୍ଭ ହେଉଛି…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"ଆଣ୍ଡ୍ରଏଡ୍ ଆରମ୍ଭ ହେଉଛି…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ଟାବଲେଟ୍ ଆରମ୍ଭ ହେଉଛି…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ଡିଭାଇସ୍ ଆରମ୍ଭ ହେଉଛି…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ଷ୍ଟୋରେଜ୍ ବଢ଼ାଯାଉଛି"</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g>ଙ୍କ ଦ୍ୱାରା ପ୍ରସ୍ତାବିତ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ ସହ ସଂଯୁକ୍ତ ହୋଇଛି"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"ଆପଣ କ’ଣ ଚାହୁଁଛନ୍ତି <xliff:g id="NAME">%s</xliff:g>, ଆପଣଙ୍କ ପାଇଁ ନେଟ୍ୱର୍କର ପ୍ରସ୍ତାବ ଦିଅନ୍ତୁ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ଆପଣ ଏକ ଉଚ୍ଚ-କ୍ୱାଲିଟୀ ବିଶିଷ୍ଟ ସେଭ୍ କରାଯାଇଥିବା ନେଟ୍ୱର୍କ ପାଖରେ ଥିବା ସମୟରେ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ପୁଣି ଅନ୍ କରନ୍ତୁ ନାହିଁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index e3fe527b1afe..eacf006627ed 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -318,7 +318,7 @@ <string name="permgroupdesc_visual" msgid="3415827902566663546">"ਤੁਹਾਡੀਆਂ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਤੱਕ ਪਹੁੰਚ"</string> <string name="permgrouprequest_visual" msgid="6907523945030290376">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਤੁਹਾਡੀਆਂ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨਾ"</string> - <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਇੱਕ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਅੰਤਰਕਿਰਿਆ ਕਰ ਰਹੇ ਹੋ"</string> + <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਉਸ ਵਿੰਡੋ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਅੰਤਰਕਿਰਿਆ ਕਰ ਰਹੇ ਹੋ"</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\'ਸਪੱਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ ਕਰੋ\' ਚਾਲੂ ਕਰਨਾ"</string> <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"ਟੈਪ ਕੀਤੀਆਂ ਆਈਟਮਾਂ ਨੂੰ ਉੱਚੀ ਆਵਾਜ਼ ਵਿੱਚ ਬੋਲਿਆ ਜਾਵੇਗਾ ਅਤੇ ਸਕ੍ਰੀਨ ਦੀ ਸੰਕੇਤਾਂ ਦੀ ਵਰਤੋਂ ਨਾਲ ਪੜਚੋਲ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ।"</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤੀ ਲਿਖਤ ਦਾ ਨਿਰੀਖਣ ਕਰਨਾ"</string> @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ਐਪ ਨੂੰ ਡੀਵਾਈਸ ਦੀਆਂ ਫ਼ੋਨ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੰਬਰ ਅਤੇ ਡੀਵਾਈਸ ਆਈ.ਡੀ. ਨਿਰਧਾਰਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ, ਇੱਕ ਕਾਲ ਕਿਰਿਆਸ਼ੀਲ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਰਿਮੋਟ ਨੰਬਰ ਇੱਕ ਕਾਲ ਨਾਲ ਕਨੈਕਟ ਹੈ ਜਾਂ ਨਹੀਂ।"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ਸਿਸਟਮ ਰਾਹੀਂ ਕਾਲਾਂ ਰੂਟ ਕਰੋ"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"ਕਾਲ ਕਰਨ ਦੇ ਅਨੁਭਵ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ ਐਪ ਨੂੰ ਇਸਦੀਆਂ ਕਾਲਾਂ ਨੂੰ ਸਿਸਟਮ ਰਾਹੀਂ ਰੂਟ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ਸਿਸਟਮ ਰਾਹੀਂ ਕਾਲਾਂ ਦੇਖੋ ਅਤੇ ਕੰਟਰੋਲ ਕਰੋ।"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ਐਪ ਨੂੰ ਡੀਵਾਈਸ \'ਤੇ ਜਾਰੀ ਕਾਲਾਂ ਦੇਖਣ ਅਤੇ ਕੰਟਰੋਲ ਕਰਨ ਦਿਓ। ਇਸ ਵਿੱਚ ਕਾਲਾਂ ਦੇ ਨੰਬਰਾਂ ਅਤੇ ਉਹਨਾਂ ਦੀ ਸਥਿਤੀ ਬਾਰੇ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੈ।"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ਕਿਸੇ ਹੋਰ ਐਪ ਤੋਂ ਕਾਲ ਜਾਰੀ ਰੱਖੋ"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"ਐਪ ਨੂੰ ਉਹ ਕਾਲ ਜਾਰੀ ਰੱਖਣ ਦਿਓ ਜਿਸਨੂੰ ਹੋਰ ਐਪ ਤੋਂ ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ਫ਼ੋਨ ਨੰਬਰ ਪੜ੍ਹੋ"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਜਟਿਲਤਾ ਪ੍ਰਾਪਤ ਕਰੋ ਅਤੇ ਬੇਨਤੀ ਕਰੋ"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ਐਪ ਨੂੰ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਜਟਿਲਤਾ ਦੇ ਪੱਧਰ ਬਾਰੇ ਜਾਣਨ ਦਿਓ (ਉੱਚ, ਮੱਧਮ, ਘੱਟ ਜਾਂ ਕੋਈ ਨਹੀਂ), ਜੋ ਲੰਬਾਈ ਦੀ ਸੰਭਵ ਰੇਂਜ ਅਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਕਿਸਮ ਦਾ ਸੰਕੇਤ ਦਿੰਦਾ ਹੈ। ਐਪ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਇੱਕ ਖਾਸ ਪੱਧਰ ਤੱਕ ਸਕ੍ਰੀਨ ਲਾਕ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੁਝਾਅ ਵੀ ਦੇ ਸਕਦੀ ਹੈ ਪਰ ਵਰਤੋਂਕਾਰ ਇਸਨੂੰ ਅਣਡਿੱਠ ਕਰ ਸਕਦੇ ਹਨ। ਨੋਟ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲਾਕ ਸਧਾਰਨ ਲਿਖਤ ਵਿੱਚ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਇਸ ਲਈ ਐਪ ਸਹੀ ਪਾਸਵਰਡ ਬਾਰੇ ਨਹੀਂ ਜਾਣਦੀ ਹੈ।"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤੋ"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ਐਪ ਨੂੰ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤਣ ਦਿੰਦਾ ਹੈ"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਵਿਵਸਥਿਤ ਕਰੋ"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ਟੈਬਲੈੱਟ ਅੱਪਡੇਟ ਹੋ ਰਿਹਾ ਹੈ…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"ਡੀਵਾਈਸ ਅੱਪਡੇਟ ਹੋ ਰਿਹਾ ਹੈ…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ਫ਼ੋਨ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ਟੈਬਲੈੱਟ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"ਡੀਵਾਈਸ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ਸਟੋਰੇਜ ਅਨੁਕੂਲ ਹੋ ਰਹੀ ਹੈ।"</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> ਵੱਲੋਂ ਸੁਝਾਏ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"ਕੀ ਤੁਸੀਂ ਚਾਹੁੰਦੇ ਹੋ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਤੁਹਾਨੂੰ ਨੈੱਟਵਰਕ ਸੁਝਾਏ?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਰੱਖਿਅਤ ਕੀਤੇ ਉੱਚ-ਗੁਣਵੱਤਾ ਵਾਲੇ ਨੈੱਟਵਰਕ ਦੇ ਨੇੜੇ ਹੋਵੋ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ਵਾਪਸ ਚਾਲੂ ਨਾ ਕਰੋ"</string> @@ -1513,7 +1522,7 @@ <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਸਵਾਈਪ ਕਰੋ।"</string> <string name="action_bar_home_description" msgid="5293600496601490216">"ਹੋਮ \'ਤੇ ਜਾਓ"</string> <string name="action_bar_up_description" msgid="2237496562952152589">"ਉੱਪਰ ਜਾਓ"</string> - <string name="action_menu_overflow_description" msgid="2295659037509008453">"ਹੋਰ ਚੋਣਾਂ"</string> + <string name="action_menu_overflow_description" msgid="2295659037509008453">"ਹੋਰ ਵਿਕਲਪ"</string> <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string> <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string> <string name="storage_internal" msgid="3570990907910199483">"ਅੰਦਰੂਨੀ ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 85303ee91992..b2bb7b085ffd 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Pozwala aplikacji na dostęp do funkcji telefonicznych urządzenia. Aplikacja z tym uprawnieniem może odczytać numer telefonu i identyfikator urządzenia, sprawdzić, czy połączenie jest aktywne, oraz poznać numer, z którym jest nawiązane połączenie."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"przekazywanie połączeń przez system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Zezwala aplikacji na przekazywanie połączeń przez system, by poprawić ich jakość."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"przeglądanie i kontrolowanie połączeń w systemie."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Zezwala aplikacji na przeglądanie i kontrolowanie trwających połączeń na urządzeniu. Dotyczy to informacji takich jak numery, z którymi nawiązane jest połączenie, oraz stan połączeń."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"kontynuuj połączenie w innej aplikacji"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Zezwala na kontynuowanie przez aplikację połączenia rozpoczętego w innej aplikacji."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"odczytywanie numerów telefonów"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Pozwala aplikacji na komunikowanie się z tagami, kartami i czytnikami NFC (Near Field Communication)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"wyłączanie blokady ekranu"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Pozwala aplikacji na wyłączenie blokady klawiatury i wszystkich związanych z tym haseł zabezpieczających. Na przykład telefon wyłącza blokadę klawiatury, gdy odbiera połączenie przychodzące, a następnie włącza ją ponownie po zakończeniu połączenia."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"uzyskiwanie informacji o stopniu trudności blokady ekranu i proszenie te informacje"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Zezwala aplikacji na poznanie stopnia złożoności blokady ekranu (wysoki, średni, niski lub brak), który wskazuje na możliwy zakres długości oraz typ blokady ekranu. Aplikacja może też zasugerować zaktualizowanie blokady ekranu pod kątem określonego stopnia trudności, ale użytkownik może to zignorować i zamknąć komunikat. Pamiętaj, że blokada ekranu nie jest zapisywana przy użyciu zwykłego tekstu, więc aplikacja nie pozna dokładnego hasła."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"używanie sprzętu biometrycznego"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Zezwala aplikacji na używanie sprzętu biometrycznego na potrzeby autoryzacji"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"zarządzanie czytnikiem linii papilarnych"</string> @@ -1123,11 +1127,11 @@ <string name="deleteText" msgid="6979668428458199034">"Usuń"</string> <string name="inputMethod" msgid="1653630062304567879">"Sposób wprowadzania tekstu"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Działania na tekście"</string> - <string name="email" msgid="4560673117055050403">"E-mail"</string> + <string name="email" msgid="4560673117055050403">"Wyślij e-maila"</string> <string name="email_desc" msgid="3638665569546416795">"Wyślij e-maila na wybrany adres"</string> <string name="dial" msgid="1253998302767701559">"Zadzwoń"</string> <string name="dial_desc" msgid="6573723404985517250">"Zadzwoń pod wybrany numer telefonu"</string> - <string name="map" msgid="5441053548030107189">"Mapa"</string> + <string name="map" msgid="5441053548030107189">"Otwórz mapę"</string> <string name="map_desc" msgid="1836995341943772348">"Pokaż wybrany adres na mapie"</string> <string name="browse" msgid="1245903488306147205">"Otwórz"</string> <string name="browse_desc" msgid="8220976549618935044">"Otwórz wybrany adres URL"</string> @@ -1139,7 +1143,7 @@ <string name="view_calendar_desc" msgid="5828320291870344584">"Wyświetl wybraną datę w kalendarzu"</string> <string name="add_calendar_event" msgid="1953664627192056206">"Zaplanuj"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Zaplanuj wydarzenie na wybraną godzinę"</string> - <string name="view_flight" msgid="7691640491425680214">"Utwór"</string> + <string name="view_flight" msgid="7691640491425680214">"Śledź"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Śledź wybrany lot"</string> <string name="translate" msgid="9218619809342576858">"Tłumacz"</string> <string name="translate_desc" msgid="4502367770068777202">"Przetłumacz zaznaczony tekst"</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet się aktualizuje…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Urządzenie się aktualizuje…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon się uruchamia…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android się uruchamia…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet się uruchamia…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Urządzenie się uruchamia…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optymalizacja pamięci."</string> @@ -1283,6 +1288,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Wszystkie sieci"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Połączono z siecią Wi‑Fi zaproponowaną przez aplikację <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Czy chcesz zezwolić aplikacji <xliff:g id="NAME">%s</xliff:g> na proponowanie sieci?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Tak"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nie"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi włączy się automatycznie"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gdy znajdziesz się w pobliżu zapisanej sieci o mocnym sygnale"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nie włączaj ponownie"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 1cbcf0fc93c9..b1a1d39d7618 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que o app acesse os recursos de telefonia do dispositivo. Esta permissão autoriza o app a determinar o número de telefone e IDs de dispositivo, quando uma chamada está ativa, e o número remoto conectado a uma chamada."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"encaminhar chamadas pelo sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permite que o app encaminhe suas chamadas por meio do sistema para melhorar a experiência com chamadas."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ver e controlar chamadas pelo sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permite que o app veja e controle chamadas em andamento no dispositivo. Isso inclui informações como número e estado das chamadas."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuar uma chamada de outro app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permite que o app continue uma chamada que foi iniciada em outro app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ler números de telefone"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que o app se comunique com leitores, cartões e etiqueta NFC (comunicação a curta distância)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desativar o bloqueio de tela"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que o app desative o bloqueio de teclas e qualquer segurança por senha associada. Por exemplo, o telefone desativa o bloqueio de telas ao receber uma chamada e o reativa quando a chamada é finalizada."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"receber e solicitar complexidade de bloqueio de tela"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"Usar hardware de biometria"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que o app use hardware de biometria para autenticação"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gerenciar hardware de impressão digital"</string> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"Excluir"</string> <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string> - <string name="email" msgid="4560673117055050403">"E-mail"</string> + <string name="email" msgid="4560673117055050403">"Mandar e-mail"</string> <string name="email_desc" msgid="3638665569546416795">"Enviar e-mail para endereço selecionado"</string> <string name="dial" msgid="1253998302767701559">"Ligar"</string> <string name="dial_desc" msgid="6573723404985517250">"Ligar para o número de telefone selecionado"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"O tablet está sendo atualizado…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"O dispositivo está sendo atualizado…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"O smartphone está iniciando…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"O Android está iniciando..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"O tablet está iniciando…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"O dispositivo está iniciando…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Otimizando o armazenamento."</string> @@ -1239,6 +1244,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">"Conectar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Conectado à rede Wi-Fi sugerida por <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Permitir que o app <xliff:g id="NAME">%s</xliff:g> faça sugestões de rede?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando você estiver perto de uma rede salva de alta qualidade"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não ativar novamente"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 6ad4ec3f91fd..ec4cf8c4daec 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que a aplicação aceda às funcionalidades de telefone do dispositivo. Esta autorização permite que a aplicação determine o número de telefone e IDs do dispositivo, se alguma chamada está ativa e qual o número remoto ligado por uma chamada."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"encaminhar chamadas através do sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permite que a aplicação encaminhe as respetivas chamadas através do sistema de modo a melhorar a experiência da chamada."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ver e controlar chamadas através do sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permite à aplicação ver e controlar as chamadas em curso no dispositivo. Isto inclui informações como números de telefone das chamadas e o estado das mesmas."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuar uma chamada a partir de outra aplicação"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permite à aplicação continuar uma chamada iniciada noutra aplicação."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ler os números de telefone"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"obter e solicitar a complexidade do bloqueio de ecrã"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"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> <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> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"O tablet está a atualizar…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"O dispositivo está a atualizar…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"O telemóvel está a iniciar…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"O Android está a iniciar…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"O tablet está a iniciar…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"O dispositivo está a iniciar…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"A otimizar o armazenamento."</string> @@ -1239,6 +1244,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="1524719325616630906">"Ligação a rede Wi‑Fi proposta por <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Pretende permitir que <xliff:g id="NAME">%s</xliff:g> lhe proponha redes?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando estiver próximo de uma rede de alta qualidade guardada."</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não reativar"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 1cbcf0fc93c9..b1a1d39d7618 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que o app acesse os recursos de telefonia do dispositivo. Esta permissão autoriza o app a determinar o número de telefone e IDs de dispositivo, quando uma chamada está ativa, e o número remoto conectado a uma chamada."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"encaminhar chamadas pelo sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permite que o app encaminhe suas chamadas por meio do sistema para melhorar a experiência com chamadas."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ver e controlar chamadas pelo sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permite que o app veja e controle chamadas em andamento no dispositivo. Isso inclui informações como número e estado das chamadas."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuar uma chamada de outro app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permite que o app continue uma chamada que foi iniciada em outro app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ler números de telefone"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que o app se comunique com leitores, cartões e etiqueta NFC (comunicação a curta distância)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desativar o bloqueio de tela"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que o app desative o bloqueio de teclas e qualquer segurança por senha associada. Por exemplo, o telefone desativa o bloqueio de telas ao receber uma chamada e o reativa quando a chamada é finalizada."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"receber e solicitar complexidade de bloqueio de tela"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"Usar hardware de biometria"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que o app use hardware de biometria para autenticação"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gerenciar hardware de impressão digital"</string> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"Excluir"</string> <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string> - <string name="email" msgid="4560673117055050403">"E-mail"</string> + <string name="email" msgid="4560673117055050403">"Mandar e-mail"</string> <string name="email_desc" msgid="3638665569546416795">"Enviar e-mail para endereço selecionado"</string> <string name="dial" msgid="1253998302767701559">"Ligar"</string> <string name="dial_desc" msgid="6573723404985517250">"Ligar para o número de telefone selecionado"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"O tablet está sendo atualizado…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"O dispositivo está sendo atualizado…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"O smartphone está iniciando…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"O Android está iniciando..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"O tablet está iniciando…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"O dispositivo está iniciando…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Otimizando o armazenamento."</string> @@ -1239,6 +1244,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">"Conectar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Conectado à rede Wi-Fi sugerida por <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Permitir que o app <xliff:g id="NAME">%s</xliff:g> faça sugestões de rede?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando você estiver perto de uma rede salva de alta qualidade"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não ativar novamente"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index dca05104ce08..5b36b9affdd1 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -450,6 +450,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicației să acceseze funcțiile de telefon ale dispozitivului. Cu această permisiune aplicația stabilește numărul de telefon și ID-urile de dispozitiv, dacă un apel este activ, precum și numărul de la distanță conectat printr-un apel."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"să direcționeze apelurile prin intermediul sistemului"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Permiteți aplicației să direcționeze apelurile prin intermediul sistemului pentru a îmbunătăți calitatea apelurilor."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Vedeți și controlați apelurile prin intermediul sistemului."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Permite aplicației să vadă și să controleze apelurile în desfășurare pe dispozitiv. Aceasta include informații ca numerele pentru apeluri și starea apelurilor."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"să continue un apel dintr-o altă aplicație"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Permite aplicației să continue un apel care a fost inițiat dintr-o altă aplicație."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"să citească numerele de telefon"</string> @@ -510,6 +512,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Permite aplicației să comunice cu etichetele, cardurile și cititoarele NFC (Near Field Communication)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"dezactivează blocarea ecranului"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite aplicației să dezactiveze blocarea tastelor și orice modalitate asociată de securizare prin parolă. De exemplu, telefonul dezactivează blocarea tastelor când se primește un apel telefonic și reactivează blocarea tastelor la terminarea apelului."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"primește și solicită complexitatea blocării ecranului"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Permite aplicației să învețe nivelul de complexitate al blocării ecranului (ridicat, mediu, scăzut sau fără) ce indică intervalul posibil de lungime a parolei și tipul de blocare a ecranului. Aplicația le poate sugera utilizatorilor să își actualizeze blocarea ecranului la un anumit nivel, dar utilizatorii pot ignora sugestia și pot naviga în continuare. Rețineți că blocarea ecranului nu este stocată ca text simplu, astfel încât aplicația să nu cunoască parola exactă."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"utilizați hardware biometric"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite aplicației să folosească hardware biometric pentru autentificare"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestionează hardware-ul pentru amprentă"</string> @@ -1104,21 +1108,21 @@ <string name="inputMethod" msgid="1653630062304567879">"Metodă de intrare"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Acțiuni pentru text"</string> <string name="email" msgid="4560673117055050403">"E-mail"</string> - <string name="email_desc" msgid="3638665569546416795">"Trimiteți e-mail la adresa selectată"</string> - <string name="dial" msgid="1253998302767701559">"Apelați"</string> - <string name="dial_desc" msgid="6573723404985517250">"Apelați numărul de telefon selectat"</string> + <string name="email_desc" msgid="3638665569546416795">"Trimiteți un e-mail la adresa selectată"</string> + <string name="dial" msgid="1253998302767701559">"Sunați"</string> + <string name="dial_desc" msgid="6573723404985517250">"Sunați la numărul de telefon selectat"</string> <string name="map" msgid="5441053548030107189">"Hartă"</string> <string name="map_desc" msgid="1836995341943772348">"Localizați adresa selectată"</string> <string name="browse" msgid="1245903488306147205">"Deschideți"</string> <string name="browse_desc" msgid="8220976549618935044">"Deschideți adresa URL selectată"</string> - <string name="sms" msgid="4560537514610063430">"Mesaj"</string> + <string name="sms" msgid="4560537514610063430">"Trimiteți mesaj"</string> <string name="sms_desc" msgid="7526588350969638809">"Trimiteți un mesaj la numărul de telefon selectat"</string> <string name="add_contact" msgid="7867066569670597203">"Adăugați"</string> - <string name="add_contact_desc" msgid="4830217847004590345">"Adăugați la persoanele din Agendă"</string> + <string name="add_contact_desc" msgid="4830217847004590345">"Adăugați în agendă"</string> <string name="view_calendar" msgid="979609872939597838">"Afișați"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"Afișați ora selectată în calendar"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Program"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"Programați evenimentul pentru momentul selectat"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"Afișați data selectată în calendar"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Programați"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"Programați evenimentul pentru data selectată"</string> <string name="view_flight" msgid="7691640491425680214">"Urmăriți"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Urmăriți zborul selectat"</string> <string name="translate" msgid="9218619809342576858">"Traduceți"</string> @@ -1201,6 +1205,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Se actualizează tableta…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Se actualizează dispozitivul.…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Pornește telefonul…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android pornește..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Pornește tableta…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Pornește dispozitivul…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Se optimizează stocarea."</string> @@ -1261,6 +1266,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Toate rețelele"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Conectat la rețeaua Wi-Fi propusă de <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Permiteți aplicației <xliff:g id="NAME">%s</xliff:g> să vă sugereze rețele?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nu"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se va activa automat"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Când vă aflați lângă o rețea salvată, de înaltă calitate"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nu reactivați"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 8278c28f32f1..ac7908c09946 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Приложение получит доступ к функциям телефона на устройстве. Кроме того, оно сможет определять номера телефонов и серийные номера моделей, состояние активности вызова, а также удаленные номера, с которыми установлено соединение."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"перенаправлять звонки в системе"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Приложение сможет перенаправлять звонки в системе с целью улучшения качества связи."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Управление вызовами через систему"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Приложение сможет управлять текущими вызовами на устройстве, а также получит доступ к сведениям о них, в том числе к номерам телефонов и статусам звонков."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"Продолжить вызов, начатый в другом приложении"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Разрешает приложению продолжить вызов, начатый в другом приложении."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"чтение номеров телефонов"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Приложение сможет обмениваться данными с NFC-метками, картами и устройствами считывания, используя NFC."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Отключение функции блокировки экрана"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Приложение сможет отключать блокировку экрана и другие функции защиты. Например, блокировка экрана будет отключаться при получении входящего вызова и включаться после завершения разговора."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"Доступ к информации об уровне сложности блокировки экрана и предоставление рекомендаций по его повышению"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Приложение получит доступ к сведениям об уровне сложности блокировки экрана (высокий, средний, низкий или не задан), в том числе о типе блокировки и длине пароля. Кроме того, оно сможет предлагать пользователям повысить уровень сложности блокировки. Эти рекомендации необязательны. Обратите внимание, что пароль не хранится в виде открытого текста и недоступен приложению."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"Использование биометрического оборудования"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Приложение сможет использовать биометрическое оборудование для аутентификации"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управление сканером отпечатков"</string> @@ -1123,7 +1127,7 @@ <string name="deleteText" msgid="6979668428458199034">"Удалить"</string> <string name="inputMethod" msgid="1653630062304567879">"Способ ввода"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string> - <string name="email" msgid="4560673117055050403">"Письмо"</string> + <string name="email" msgid="4560673117055050403">"Написать письмо"</string> <string name="email_desc" msgid="3638665569546416795">"Отправить письмо выбранному адресату"</string> <string name="dial" msgid="1253998302767701559">"Позвонить"</string> <string name="dial_desc" msgid="6573723404985517250">"Позвонить по выбранному номеру"</string> @@ -1137,7 +1141,7 @@ <string name="add_contact_desc" msgid="4830217847004590345">"Добавить в контакты"</string> <string name="view_calendar" msgid="979609872939597838">"Открыть"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Посмотреть выбранный день в календаре"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Расписание"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Запланировать"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Запланировать событие на выбранный день"</string> <string name="view_flight" msgid="7691640491425680214">"Отследить"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Отслеживать выбранный рейс"</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Обновление планшета…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Обновление устройства…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Запуск телефона…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Запуск Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Запуск планшета…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Запуск устройства…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимизация хранилища…"</string> @@ -1283,6 +1288,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="1524719325616630906">"Установлено подключение к сети Wi‑Fi, найденной приложением \'<xliff:g id="NAME">%s</xliff:g>\'"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Разрешить приложению \'<xliff:g id="NAME">%s</xliff:g>\' предлагать вам сети?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Когда вы будете в зоне действия сохраненной сети с хорошим сигналом."</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не включать снова"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 7a43ecd8465f..6486f3a2a0a4 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"උපාංගයේ දුරකථන විශේෂාංග වෙත ප්රවේශයට යෙදුමට ඉඩ දෙයි. ඇමතුම සක්රිය වුවත්, සහ ඇමතුමකින් දුරස්ථ අංකය සම්බන්ධ වුවත් දුරකථන අංකය සහ උපාංග ID හඳුනා ගැනීමට මෙම අවසරය යෙදුමට ඉඩ දෙයි."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"පද්ධතිය හරහා ඇමතුම් මාර්ගගත කරන්න"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"ඇමතුම් අත්දැකීම වැඩිදියුණු කිරීම සඳහා යෙදුමට පද්ධතිය හරහා එහි ඇමතුම් මාර්ගගත කිරීමට ඉඩ දෙයි."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"පද්ධතිය හරහා ඇමතුම් බලන්න සහ පාලනය කරන්න."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"යෙදුමට උපාංගයෙහි පවතින ඇමතුම් බැලීමට සහ පාලනය කිරීමට ඉඩ දෙයි මෙහි ඇමතුම් සඳහා ඇමතුම් අංක සහ ඇමතුම්වල තත්ත්වය වැනි තොරතුරු ඇතුළත් වේ."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"වෙනත් යෙදුමක් වෙතින් වන ඇමතුමක් දිගටම කරගෙන යන්න"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"වෙනත් යෙදුමක ආරම්භ කරන ලද ඇමතුමක් දිගටම කරගෙන යාමට යෙදුමට ඉඩ දෙයි."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"දුරකථන අංක කියවන්න"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"තිර අගුලු සංකිර්ණය ලබා ගන්න සහ ඉල්ලන්න"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"තිර අගුලෙහි තිබිය හැකි දිගෙහි පරාසය හා වර්ගයේ පිළිබිඹු කරන, තිර අගුලු සංකීර්ණතා මට්ටම (ඉහළ, මධ්යම, අඩු හෝ රහිත) දැන ගැනීමට යෙදුමට ඉඩ දෙයි. තිරයේ අගුල නිශ්චිත මට්ටමක් වෙත යාවත්කාලීන කරන බවද මෙම යෙදුම පරිශීලකයින්ට යෝජනා කළ හැකිය. නමුත් පරිශීලකයන්ට නිදහසේ නොසලකා හැර සංචාලනය කළ හැකිය. තිර අලුල සරල පෙළ තුළ ගබඩා කර නැති බව සලකන්න එම නිසා යෙදුම නිවැරදි මුරපදය නොදනී."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ජීවමිතික දෘඪාංග භාවිත කරන්න"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"සත්යාපනය සඳහා ජීවමිතික දෘඪාංග භාවිත කිරීමට යෙදුමට ඉඩ දෙයි"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ඇඟිලි සලකුණු දෘඩාංග කළමනාකරණය කිරීම."</string> @@ -1183,6 +1187,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ටැබ්ලට් පරිගණකය යාවත්කාලීන කරමින්..."</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"උපාංගය යාවත්කාලීන කරමින්..."</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"දුරකථනය ආරම්භ කරමින්…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android ආරම්භ කරමින්…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ටැබ්ලට් පරිගණකය ආරම්භ කරමින්…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"උපාංගය ආරම්භ කරමින්…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ආචයනය ප්රශස්තිකරණය කිරීම."</string> @@ -1241,6 +1246,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> විසින් යෝජිත Wi-Fi ජාලයට සම්බන්ධ වුණි"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g>ඔබට ඔබ සඳහා ජාල යෝජනා කිරීමට අවශ්යද?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ඔබ උසස් තත්ත්වයේ සුරැකි ජාලයක් අවට සිටින විට"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"නැවත ක්රියාත්මක නොකරන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 7e158c2bbb58..66d6ef6a4ee4 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikácii pristupovať k telefónnym funkciám zariadenia. Aplikácia s týmto povolením môže určiť telefónne číslo a ID zariadenia, či práve prebieha hovor, a vzdialené číslo, s ktorým je prostredníctvom hovoru nadviazané spojenie."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"presmerovanie hovorov cez systém"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Umožňuje aplikácii presmerovať hovory cez systém na účely zlepšenia kvality hovorov."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"zobrazenie a kontrola hovorov prostredníctvom systému."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Umožňuje aplikácii zobrazovať a kontrolovať prebiehajúce hovory v zariadení. Táto možnosť zahŕňa údaje, akými sú napríklad čísla jednotlivých hovorov alebo stav hovorov."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"pokračovať v hovore z inej aplikácie"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Umožňuje aplikácii pokračovať v hovore začatom v inej aplikácii."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čítanie telefónnych čísel"</string> @@ -513,6 +515,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"získavať a vyžadovať zložitosť zámky obrazovky"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"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> <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> @@ -1123,15 +1127,15 @@ <string name="deleteText" msgid="6979668428458199034">"Odstrániť"</string> <string name="inputMethod" msgid="1653630062304567879">"Metóda vstupu"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Operácie s textom"</string> - <string name="email" msgid="4560673117055050403">"E-mail"</string> + <string name="email" msgid="4560673117055050403">"Poslať e-mail"</string> <string name="email_desc" msgid="3638665569546416795">"Napísať na vybratú e-mailovú adresu"</string> <string name="dial" msgid="1253998302767701559">"Volať"</string> <string name="dial_desc" msgid="6573723404985517250">"Zavolať na vybraté telefónne číslo"</string> - <string name="map" msgid="5441053548030107189">"Mapa"</string> + <string name="map" msgid="5441053548030107189">"Otvoriť mapu"</string> <string name="map_desc" msgid="1836995341943772348">"Nájsť vybranú adresu"</string> <string name="browse" msgid="1245903488306147205">"Otvoriť"</string> <string name="browse_desc" msgid="8220976549618935044">"Otvoriť vybratú webovú adresu"</string> - <string name="sms" msgid="4560537514610063430">"Správa"</string> + <string name="sms" msgid="4560537514610063430">"Poslať správu"</string> <string name="sms_desc" msgid="7526588350969638809">"Napísať SMS na vybraté telefónne číslo"</string> <string name="add_contact" msgid="7867066569670597203">"Pridať"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Pridať medzi kontakty"</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet sa aktualizuje…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Zariadenie sa aktualizuje…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefón sa spúšťa…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Systém Android sa spúšťa…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet sa spúšťa…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Zariadenie sa spúšťa…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimalizuje sa úložisko"</string> @@ -1283,6 +1288,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="1524719325616630906">"Pripojené k sieti Wi‑Fi navrhnutej používateľom <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Chcete umožniť používateľovi <xliff:g id="NAME">%s</xliff:g> navrhovať siete za vás?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Keď budete v blízkosti kvalitnej uloženej siete"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Znova nezapínať"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 0790e904ec18..dcaa4f5d04d6 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Aplikaciji omogoča dostop do funkcij telefona v napravi. S tem dovoljenjem lahko aplikacija določi telefonsko številko in ID-je naprave, določi lahko tudi, ali je klic aktiven, in oddaljeno številko, s katero je klic povezan."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"Usmeri klice prek sistema"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dovoli, da aplikacija usmeri klice prek sistema, da se tako izboljša izkušnja klicanja."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ogled in nadzor klicev prek sistema."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Aplikaciji dovoljuje, da si ogleda in nadzoruje aktivne klice v napravi. To vključuje informacije, kot so telefonske številke klicev in stanje klicev."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"Nadaljevanje klica iz druge aplikacije"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Aplikaciji dovoljuje nadaljevanje klica, ki se je začel v drugi aplikaciji."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"branje telefonskih številk"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Podpira komunikacijo med računalnikom in oznakami, karticami in bralniki komunikacije s tehnologijo bližnjega polja."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogočanje zaklepanja zaslona"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji dovoljuje, da onemogoči zaklep tipkovnice in morebitno povezano varnostno geslo. Telefon na primer onemogoči zaklep tipkovnice pri dohodnem klicu ter vnovič omogoči zaklep, ko je klic končan."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"pridobi in zahtevaj zapletenost zaklepanja zaslona"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Aplikaciji dovoljuje, da pridobi raven zapletenosti zaklepanja zaslona (visoka, srednja, nizka ali brez), ki označuje možen obseg dolžine in vrsto zaklepanja zaslona. Aplikacija lahko tudi predlaga uporabnikom, da posodobijo zaklepanje zaslona na določeno raven, vendar lahko uporabniki to opozorilo prezrejo in ga zaprejo tako, da se pomaknejo stran. Upoštevajte, da zaklepanje zaslona ni shranjeno v navadnem besedilu, tako da aplikacija ne pozna točnega gesla."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"uporaba strojne opreme za biometrične podatke"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Aplikaciji omogoča uporabo strojne opreme za biometrične podatke za preverjanje pristnosti"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje strojne opreme za prstne odtise"</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablični računalnik se posodablja …"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Naprava se posodablja …"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon se zaganja …"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android se zaganja …"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablični računalnik se zaganja …"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Naprava se zaganja …"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje shrambe."</string> @@ -1283,6 +1288,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Vsa omrežja"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Vzpostavljena povezava z omrežjem Wi‑Fi na predlog aplikacije <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Ali želite aplikaciji <xliff:g id="NAME">%s</xliff:g> dovoliti predlaganje omrežij?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Povezava Wi‑Fi se bo samodejno vklopila"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Ko ste v bližini zanesljivega shranjenega omrežja"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne vklopi znova"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 5c001ed568f7..413ff8a51b19 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lejon aplikacionin të hyjë në funksionet telefonike të pajisjes. Kjo leje i mundëson aplikacionit të përcaktojë numrin e telefonit dhe ID-të e pajisjes, nëse një telefonatë është aktive apo nëse numri në distancë është i lidhur me një telefonatë."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"kalon telefonatat përmes sistemit"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Lejon që aplikacioni të kalojë telefonatat përmes sistemit për të përmirësuar përvojën e telefonatës."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Shiko dhe kontrollo telefonatat nëpërmjet sistemit."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Lejon që aplikacioni të shikojë dhe të kontrollojë telefonatat në vazhdim në pajisje. Kjo përfshin informacione si p.sh. numrat e telefonatave për telefonatat dhe gjendjen e telefonatave."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"vazhdo një telefonatë nga një aplikacion tjetër"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Lejon që aplikacioni të vazhdojë një telefonatë që është nisur në një aplikacion tjetër."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lexo numrat e telefonit"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Lejon aplikacionin të komunikojë me etiketimet e \"Komunikimit të fushës së afërt (NFC)\", kartat dhe lexuesit."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"çaktivizo kyçjen e ekranit"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lejon aplikacionin të çaktivizojë kyçjen e tasteve dhe çdo mbrojtje të lidhur me fjalëkalimin. Për shembull, telefoni çaktivizon kyçjen e tasteve kur merr një telefonatë hyrëse, pastaj riaktivizon kyçjen e tasteve kur mbaron telefonata."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"merr dhe kërko kompleksitetin e kyçjes së ekranit"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Lejo që aplikacioni të mësojë nivelin e kompleksitetit të kyçjes së ekranit (i lartë, i mesëm, i ulët ose asnjë), që tregon gamën e mundshme të gjatësisë dhe llojin e kyçjes së ekranit. Aplikacioni mund t\'u sugjerojë gjithashtu përdoruesve që të përditësojnë kyçjen e ekranit në një nivel të caktuar, por përdoruesit mund ta shpërfillin lirshëm dhe të navigojnë më tej. Ki parasysh se kyçja e ekranit nuk ruhet në tekst të thjeshtë, prandaj aplikacioni nuk e di fjalëkalimin e saktë."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"përdor harduerin biometrik"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"E lejon aplikacionin që të përdorë harduerin biometrik për vërtetimin"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"të menaxhojë harduerin e gjurmës së gishtit"</string> @@ -1087,19 +1091,19 @@ <string name="email_desc" msgid="3638665569546416795">"Dërgo email tek adresa e zgjedhur"</string> <string name="dial" msgid="1253998302767701559">"Telefono"</string> <string name="dial_desc" msgid="6573723404985517250">"Telefono në numrin e zgjedhur të telefonit"</string> - <string name="map" msgid="5441053548030107189">"Harta"</string> + <string name="map" msgid="5441053548030107189">"Hap hartën"</string> <string name="map_desc" msgid="1836995341943772348">"Gjej adresën e zgjedhur"</string> <string name="browse" msgid="1245903488306147205">"Hap"</string> <string name="browse_desc" msgid="8220976549618935044">"Hap URL-në e zgjedhur"</string> - <string name="sms" msgid="4560537514610063430">"Mesazh"</string> + <string name="sms" msgid="4560537514610063430">"Dërgo mesazh"</string> <string name="sms_desc" msgid="7526588350969638809">"Dërgo mesazh te numri i zgjedhur i telefonit"</string> <string name="add_contact" msgid="7867066569670597203">"Shto"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Shto te kontaktet"</string> <string name="view_calendar" msgid="979609872939597838">"Shiko"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Shiko kohën e zgjedhur në kalendar"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Orari"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Planifiko"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Planifiko ngjarjen për kohën e zgjedhur"</string> - <string name="view_flight" msgid="7691640491425680214">"Pjesë muzikore"</string> + <string name="view_flight" msgid="7691640491425680214">"Monitoro"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Monitoro fluturimin e zgjedhur"</string> <string name="translate" msgid="9218619809342576858">"Përkthe"</string> <string name="translate_desc" msgid="4502367770068777202">"Përkthe tekstin e zgjedhur"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tableti po përditësohet…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Pajisja po përditësohet…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefoni po niset…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"\"Androidi\" po fillon…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tableti po niset…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Pajisja po niset…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Po përshtat ruajtjen."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Të gjitha rrjetet"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Lidhur me rrjetin Wi‑Fi të propozuar nga <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Dëshiron të lejosh që <xliff:g id="NAME">%s</xliff:g> të propozojë rrjetet për ty?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Po"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Jo"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi do të aktivizohet automatikisht"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kur ndodhesh pranë një rrjeti të ruajtur me cilësi të lartë"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Mos e aktivizo përsëri"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index b64f6febdd32..8f8fe0ed0a06 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -450,6 +450,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дозвољава апликацији да приступа функцијама телефона на уређају. Ова дозвола омогућава апликацији да утврди број телефона и ИД-ове уређаја, затим да ли је позив активан, као и број даљинског уређаја са којим је успостављен позив."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"преусмеравање позива преко система"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дозвољава апликацији да преусмерава позиве преко система да би побољшала доживљај позивања."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"преглед и контрола позива преко система."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Дозвољава апликацији да прегледа и контролише тренутне позиве на уређају. То обухвата информације попут бројева телефона и статуса позива."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"настави позив у другој апликацији"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Дозвољава апликацији да настави позив који је започет у другој апликацији."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"читање бројева телефона"</string> @@ -510,6 +512,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"добијање и тражење нивоа сложености закључавања екрана"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају закључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за закључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"користи биометријски хардвер"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дозвољава апликацији да користи биометријски хардвер за потврду идентитета"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управљај хардвером за отиске прстију"</string> @@ -1107,7 +1111,7 @@ <string name="email_desc" msgid="3638665569546416795">"Пошаљите имејл на изабрану адресу"</string> <string name="dial" msgid="1253998302767701559">"Позови"</string> <string name="dial_desc" msgid="6573723404985517250">"Позовите изабрани број телефона"</string> - <string name="map" msgid="5441053548030107189">"Мапа"</string> + <string name="map" msgid="5441053548030107189">"Прикажи на мапи"</string> <string name="map_desc" msgid="1836995341943772348">"Пронађите изабрану адресу"</string> <string name="browse" msgid="1245903488306147205">"Отвори"</string> <string name="browse_desc" msgid="8220976549618935044">"Отворите изабрани URL"</string> @@ -1201,6 +1205,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Таблет се ажурира…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Уређај се ажурира…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Телефон се покреће…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android се покреће…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Таблет се покреће…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Уређај се покреће…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Меморија се оптимизује."</string> @@ -1261,6 +1266,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="1524719325616630906">"Повезани сте са Wi‑Fi мрежом коју предлаже <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Желите ли да дозволите да вам <xliff:g id="NAME">%s</xliff:g> предлаже мреже?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Када сте у близини сачуване мреже високог квалитета"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не укључуј поново"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 18c66ed9dc51..cd5580d2970e 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillåter att appen kommer åt enhetens telefonfunktioner. Med den här behörigheten tillåts appen att identifiera mobilens telefonnummer och enhets-ID, om ett samtal pågår och vilket nummer samtalet är kopplat till."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"dirigera samtal via systemet"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Appen tillåts att dirigera samtal via systemet för att förbättra samtalsupplevelsen."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"visa och styra samtal via systemet."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Tillåter att appen kan visa och styra pågående samtal på enheten. Detta omfattar information som telefonnummer för samtal och samtalens status."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"fortsätta ett samtal från en annan app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Tillåter att appen fortsätter ett samtal som har startats i en annan app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"läsa telefonnummer"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Tillåter att appen kommunicerar med etiketter, kort och läsare för närfältskommunikation (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"inaktivera skärmlåset"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tillåter att appen inaktiverar tangentlåset och tillhörande lösenordsskydd. Ett exempel kan vara att tangentlåset inaktiveras vid inkommande samtal och aktiveras igen när samtalet är avslutat."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"hämta och begär komplexitet för låsskärmen"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Tillåter att appen får reda på komplexitetsnivån för skärmlåset (hög, mellan, låg eller ingen). Detta ger en indikation på skärmlåsets möjliga längd och typ. Appen kan även föreslå att skärmlåset uppdateras till en viss nivå, men användare kan ignorera förslaget och fortsätta navigera. Observera att skärmlåset inte lagras i vanlig text så appen får inte reda på det exakta lösenordet."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"använd biometrisk maskinvara"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Tillåter att appen använder biometrisk maskinvara vid autentisering"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"hantera maskinvara för fingeravtryck"</string> @@ -1087,7 +1091,7 @@ <string name="email_desc" msgid="3638665569546416795">"Skicka e-post till vald adress"</string> <string name="dial" msgid="1253998302767701559">"Ring"</string> <string name="dial_desc" msgid="6573723404985517250">"Ring valt telefonnummer"</string> - <string name="map" msgid="5441053548030107189">"Karta"</string> + <string name="map" msgid="5441053548030107189">"Öppna karta"</string> <string name="map_desc" msgid="1836995341943772348">"Hitta den valda adressen"</string> <string name="browse" msgid="1245903488306147205">"Öppna"</string> <string name="browse_desc" msgid="8220976549618935044">"Öppna vald webbadress"</string> @@ -1097,9 +1101,9 @@ <string name="add_contact_desc" msgid="4830217847004590345">"Lägg till i Kontakter"</string> <string name="view_calendar" msgid="979609872939597838">"Visa"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Visa vald tid i kalendern"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Schema"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Schemalägg"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Schemalägg händelse på den valda tiden"</string> - <string name="view_flight" msgid="7691640491425680214">"Spår"</string> + <string name="view_flight" msgid="7691640491425680214">"Spåra"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Spåra valt flyg"</string> <string name="translate" msgid="9218619809342576858">"Översätt"</string> <string name="translate_desc" msgid="4502367770068777202">"Översätt markerad text"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Surfplattan uppdateras …"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Enheten uppdateras …"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Mobilen startar …"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android startar …"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Surfplattan startar …"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Enheten startar …"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Lagringsutrymmet optimeras."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alla nätverk"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Ansluten till Wi-Fi-nätverket som föreslogs i <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Vill du tillåta att <xliff:g id="NAME">%s</xliff:g> föreslår nätverk till dig?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi aktiveras automatiskt"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"När du är i närheten av ett sparat nätverk av hög kvalitet"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Återaktivera inte"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 51ac513b8885..bc3e4ad903a0 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Huruhusu programu kufikia vipengele vya simu vilivyo kwenye kifaa. Idhini hii inaruhusu programu kutambua nambari ya simu na kifaa, kama kuna simu inayopigwa, na nambari ya mbali iliyounganishwa kwenye simu."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"elekeza simu kupitia mfumo"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Huruhusu programu kuelekeza simu zake kupitia mfumo ili kuboresha hali ya kupiga simu."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"kuona na kudhibiti simu kupitia mfumo."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Inaruhusu programu ione na kudhibiti simu zinazoendelea kupigwa kwenye kifaa. Hii inajumuisha maelezo kama vile nambari za simu zinazopigwa na hali ya simu."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"endelea na simu kutoka programu nyingine"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Huruhusu programu kuendelea na simu ambayo ilianzishwa katika programu nyingine."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"kusoma nambari za simu"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Inaruhusu programu kuwasiliana na lebo, kadi na wasomaji wa Near Field Communication (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"zima kufuli la skrini yako"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Inaruhusu programu kulemaza ufunguo wa vitufe na usalama mwingine ambata wa nenosiri. Kwa mfano, simu inalemaza ufunguo wa viitufe inapopokea simu inayoingia, kisha inawezesha upya ufunguo wa vitufe wakati simu inapokamilika."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"kupata na kuomba kiwango cha uchangamano wa kufunga skrini"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Huruhusu programu kupata maelezo kuhusu kiwango cha uchangamano wa kufunga skrini (juu, wastani, chini au hakuna), ambacho huashiria urefu unaowezekana na aina ya kufunga skrini. Programu pia inaweza kupendekeza kuwa watumiaji wasasishe kipengele cha kufunga skrini kiwe cha kiwango fulani lakini watumiaji wanaweza kupuuza kwa hiari na waende kwingine. Kumbuka kuwa maelezo ya kufunga skrini hayahifadhiwi kama maandishi, hivyo programu haitambui nenosiri mahususi."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"tumia maunzi ya kibiolojia"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Huruhusu programu itumie maunzi ya kibiolojia katika uthibitishaji"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"dhibiti maunzi ya kitambulisho"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Kompyuta kibao inasasishwa…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Kifaa kinasasishwa…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Simu inawaka…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Inaanzisha Android..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Kompyuta kibao inawaka…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Kifaa kiwaka…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Inaboresha hifadhi."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gusa ili uone mitandao yote"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Mitandao yote"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Imeunganishwa na mtandao wa Wi‑Fi uliopendekezwa na <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Je, ungependa kuruhusu <xliff:g id="NAME">%s</xliff:g> akupendekezee mitandao?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ndiyo"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hapana"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi itawashwa kiotomatiki"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Unapokuwa karibu na mtandao uliohifadhiwa wenye ubora wa juu"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Usiwashe tena"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 1f2c6a655985..22da7b027b6e 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"சாதனத்தின் மொபைல் அம்சங்களை அணுகப் பயன்பாட்டை அனுமதிக்கிறது. மொபைல் மற்றும் சாதன ஐடிகள், அழைப்பு செயலில் உள்ளதா மற்றும் அழைப்பு மூலம் இணைக்கப்பட்ட தொலைக் கட்டுப்பாட்டு எண் ஆகியவற்றைத் தீர்மானிக்க இந்த அனுமதி பயன்பாட்டை அனுமதிக்கிறது."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"சிஸ்டம் மூலம் அழைப்புகளை ரூட் செய்தல்"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"அழைக்கும் அனுபவத்தை மேம்படுத்தும் பொருட்டு, சிஸ்டம் மூலம் தனது அழைப்புகளை ரூட் செய்ய பயன்பாட்டை அனுமதிக்கும்."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"சிஸ்டம் மூலமாக அழைப்புகளைப் பார்த்தலும் கட்டுப்படுத்துதலும்."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"செயலில் உள்ள அழைப்புகளைச் சாதனத்தில் பார்க்கவும் கட்டுப்படுத்தவும் ஆப்ஸை அனுமதிக்கிறது. அழைப்பு எண்கள் மற்றும் அழைப்புகளின் நிலை போன்ற தகவல்களும் இதில் அடங்கும்."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"மற்றொரு பயன்பாட்டிலிருந்து அழைப்பைத் தொடருதல்"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"மற்றொரு பயன்பாட்டில் தொடங்கப்பட்ட அழைப்பைத் தொடருவதற்கு, பயன்பாட்டை அனுமதிக்கிறது."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ஃபோன் எண்களைப் படித்தல்"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"திரைப் பூட்டு தொடர்பான சிக்கலைத் தீர்க்க அனுமதி பெறுதல்"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையைப் பற்றி (அதிகம், நடுத்தரம், குறைவு அல்லது ஏதுமில்லை) அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கிறது. இதன் மூலம் திரைப் பூட்டின் திறனையும் வகையையும் பற்றி அறிந்துகொள்ள முடிகிறது. மேலும் திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையை குறிப்பிட்ட நிலைக்குப் புதுப்பித்துக்கொள்ளலாம் என்பதையும் ஆப்ஸ் பயனர்களுக்குப் பரிந்துரைக்கலாம். ஆனால் தங்கள் விருப்பப்படி அவற்றைப் பயனர்கள் ஏற்கவோ நிராகரிக்கவோ செய்யலாம். கவனத்திற்கு: திரைப் பூட்டு எளிய உரையிலான கடவுச்சொல்லால் சேமிக்கப்படுவதில்லை என்பதால் சரியான கடவுச்சொல்லை ஆப்ஸால் அறிய இயலாது."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்து"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்தி அங்கீகரிப்பதற்கு, பயன்பாட்டை அனுமதிக்கும்"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"கைரேகை வன்பொருளை நிர்வகி"</string> @@ -1083,7 +1087,7 @@ <string name="deleteText" msgid="6979668428458199034">"நீக்கு"</string> <string name="inputMethod" msgid="1653630062304567879">"உள்ளீட்டு முறை"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"உரை நடவடிக்கைகள்"</string> - <string name="email" msgid="4560673117055050403">"மின்னஞ்சல்"</string> + <string name="email" msgid="4560673117055050403">"மின்னஞ்சல் அனுப்பு"</string> <string name="email_desc" msgid="3638665569546416795">"தேர்ந்தெடுத்த முகவரிக்கு மின்னஞ்சல் அனுப்பும்"</string> <string name="dial" msgid="1253998302767701559">"அழை"</string> <string name="dial_desc" msgid="6573723404985517250">"தேர்ந்தெடுத்த ஃபோன் எண்ணை அழைக்கும்"</string> @@ -1091,13 +1095,13 @@ <string name="map_desc" msgid="1836995341943772348">"தேர்ந்தெடுத்த முகவரிக்கான வரைபடத்தைத் திறக்கும்"</string> <string name="browse" msgid="1245903488306147205">"திற"</string> <string name="browse_desc" msgid="8220976549618935044">"தேர்ந்தெடுத்த URLஐத் திறக்கும்"</string> - <string name="sms" msgid="4560537514610063430">"செய்தி"</string> + <string name="sms" msgid="4560537514610063430">"செய்தி அனுப்பு"</string> <string name="sms_desc" msgid="7526588350969638809">"தேர்ந்தெடுத்த ஃபோன் எண்ணிற்குச் செய்தி அனுப்பும்"</string> <string name="add_contact" msgid="7867066569670597203">"சேர்"</string> <string name="add_contact_desc" msgid="4830217847004590345">"தொடர்புகளில் சேர்க்கும்"</string> <string name="view_calendar" msgid="979609872939597838">"காண்பி"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"கேலெண்டரில் தேர்ந்தெடுத்த நேரத்தைக் காட்டும்"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"திட்டமிடுதல்"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"திட்டமிடு"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"தேர்ந்தெடுத்த நேரத்திற்கு நிகழ்வைத் திட்டமிடும்"</string> <string name="view_flight" msgid="7691640491425680214">"கண்கானி"</string> <string name="view_flight_desc" msgid="3876322502674253506">"தேர்ந்தெடுத்த விமானத்தைக் கண்காணிக்கும்"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"டேப்லெட் புதுப்பிக்கப்படுகிறது…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"சாதனம் புதுப்பிக்கப்படுகிறது…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"மொபைல் தொடங்குகிறது…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android துவங்குகிறது..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"டேப்லெட் தொடங்குகிறது…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"சாதனம் தொடங்குகிறது…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"சேமிப்பகத்தை உகந்ததாக்குகிறது."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> இன் வைஃபை நெட்வொர்க்குடன் இணைக்கப்பட்டது"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"உங்களுக்கு நெட்வொர்க்குகளைக் காட்ட <xliff:g id="NAME">%s</xliff:g>ஐ அனுமதிக்கவா?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"சேமித்த, உயர்தர நெட்வொர்க்கிற்கு அருகில் இருக்கும்போது"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"மீண்டும் ஆன் செய்யாதே"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index fd853fb7c85e..1cc0274d4cc2 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"పరికరం యొక్క ఫోన్ ఫీచర్లను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ సక్రియంగా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్ను కనుగొనడానికి యాప్ను అనుమతిస్తుంది."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"కాల్లను సిస్టమ్ ద్వారా వెళ్లేలా చేయి"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"కాలింగ్ అనుభవాన్ని మెరుగుపరచడం కోసం తన కాల్లను సిస్టమ్ ద్వారా వెళ్లేలా చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"సిస్టమ్ ద్వారా కాల్లను చూసి, నియంత్రించండి."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"పరికరంలో కొనసాగుతున్న కాల్లను చూడడానికి మరియు నియంత్రించడానికి యాప్ను అనుమతిస్తుంది. ఇందులో కాల్ కోసం కాల్ల నంబర్లు మరియు రాష్ట్ర కాల్ వంటి సమాచారం ఉంటుంది."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"మరో యాప్ నుండి కాల్ని కొనసాగించండి"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"మరో యాప్లో ప్రారంభించిన కాల్ని కొనసాగించడానికి యాప్ని అనుమతిస్తుంది."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ఫోన్ నంబర్లను చదువు"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"స్క్రీన్ లాక్ పాస్వర్డ్ బల స్థాయిని పొందడం మరియు అభ్యర్ధించడం"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"ఇది మీ స్క్రీన్ లాక్ పాస్వర్డ్ బల స్థాయి (తీవ్రంగా ఉండాలా లేదా ఓ మోస్తరుగా ఉండాలా లేదా తక్కువ తీవ్రంగా గానీ అసలు ఏదీ కాకుండా ఉండాలా) అనే విషయాన్ని గుర్తుంచుకోవడానికి యాప్కి అనుమతిస్తుంది, అలాగే పాస్వర్డ్ పొడుగు ఎంత ఉండాలీ, ఏ రకమైన స్క్రీన్ లాక్ పధ్ధతి అనుసరించాలో సూచిస్తుంది. యాప్ ఇంకా స్క్రీన్ లాక్ పాస్వర్డ్ బల స్థాయిని ఏ స్థాయిలో సెట్ చేసుకుంటే బాగుంటుందో వినియోగదారులకు తెలపగలదు కానీ వినియోగదారులు దాని సూచనలను పట్టించుకోకుండా వారి ఇష్టం మేరకు చక్కగా సెట్ చేసుకోవచ్చు. మీకో ముఖ్యమైన మాట స్క్రీన్ లాక్ పాస్వర్డ్ అనేది సాదా వచన రూపంలో నిల్వ చేయబడదు, కనుక అసలు మీరు పాస్వర్డ్ ఏం పెట్టారనే విషయం యాప్కి తెలియదు."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"బయోమెట్రిక్ హార్డ్వేర్ని ఉపయోగించు"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ప్రమాణీకరణ కోసం బయోమెట్రిక్ హార్డ్వేర్ను ఉపయోగించడానికి యాప్ని అనుమతిస్తుంది"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"వేలిముద్ర హార్డ్వేర్ని నిర్వహించడానికి అనుమతి"</string> @@ -1083,27 +1087,27 @@ <string name="deleteText" msgid="6979668428458199034">"తొలగించు"</string> <string name="inputMethod" msgid="1653630062304567879">"ఇన్పుట్ పద్ధతి"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"వచనానికి సంబంధించిన చర్యలు"</string> - <string name="email" msgid="4560673117055050403">"ఇమెయిల్"</string> + <string name="email" msgid="4560673117055050403">"ఇమెయిల్ చేయి"</string> <string name="email_desc" msgid="3638665569546416795">"ఎంచుకున్న చిరునామాకు ఇమెయిల్ను పంపుతుంది"</string> - <string name="dial" msgid="1253998302767701559">"కాల్ చేయండి"</string> + <string name="dial" msgid="1253998302767701559">"కాల్ చేయి"</string> <string name="dial_desc" msgid="6573723404985517250">"ఎంచుకున్న ఫోన్ నంబర్కు కాల్ చేస్తుంది"</string> - <string name="map" msgid="5441053548030107189">"మ్యాప్"</string> + <string name="map" msgid="5441053548030107189">"మ్యాప్ తెరువు"</string> <string name="map_desc" msgid="1836995341943772348">"ఎంచుకున్న చిరునామాను గుర్తించు"</string> - <string name="browse" msgid="1245903488306147205">"తెరవండి"</string> + <string name="browse" msgid="1245903488306147205">"తెరువు"</string> <string name="browse_desc" msgid="8220976549618935044">"ఎంచుకున్న URLని తెరుస్తుంది"</string> - <string name="sms" msgid="4560537514610063430">"సందేశం"</string> + <string name="sms" msgid="4560537514610063430">"సందేశం పంపు"</string> <string name="sms_desc" msgid="7526588350969638809">"ఎంచుకున్న ఫోన్ నంబర్కి సందేశం పంపుతుంది"</string> - <string name="add_contact" msgid="7867066569670597203">"జోడించండి"</string> + <string name="add_contact" msgid="7867066569670597203">"జోడించు"</string> <string name="add_contact_desc" msgid="4830217847004590345">"పరిచయాలకు జోడిస్తుంది"</string> - <string name="view_calendar" msgid="979609872939597838">"చూడండి"</string> + <string name="view_calendar" msgid="979609872939597838">"చూడు"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"ఎంచుకున్న సమయాన్ని క్యాలెండర్లో వీక్షించండి"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"షెడ్యూల్"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"షెడ్యూల్ చేయి"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"ఎంచుకున్న సమయానికి ఈవెంట్ను షెడ్యూల్ చేస్తుంది"</string> - <string name="view_flight" msgid="7691640491425680214">"ట్రాక్ చేయండి"</string> + <string name="view_flight" msgid="7691640491425680214">"ట్రాక్ చేయి"</string> <string name="view_flight_desc" msgid="3876322502674253506">"ఎంచుకున్న విమానాన్ని ట్రాక్ చేస్తుంది"</string> - <string name="translate" msgid="9218619809342576858">"అనువదించండి"</string> + <string name="translate" msgid="9218619809342576858">"అనువదించు"</string> <string name="translate_desc" msgid="4502367770068777202">"ఎంచుకున్న వచనాన్ని అనువదించండి"</string> - <string name="define" msgid="7394820043869954211">"నిర్వచించండి"</string> + <string name="define" msgid="7394820043869954211">"నిర్వహించు"</string> <string name="define_desc" msgid="7910883642444919726">"ఎంచుకున్న వచనాన్ని నిర్వచించండి"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"నిల్వ ఖాళీ అయిపోతోంది"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"కొన్ని సిస్టమ్ కార్యాచరణలు పని చేయకపోవచ్చు"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"టాబ్లెట్ అప్డేట్ అవుతోంది…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"పరికరం అప్డేట్ అవుతోంది…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"ఫోన్ ప్రారంభమవుతోంది…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android ప్రారంభమవుతోంది…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"టాబ్లెట్ ప్రారంభమవుతోంది…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"పరికరం ప్రారంభమవుతోంది…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"నిల్వను అనుకూలపరుస్తోంది."</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> సూచన మేరకు Wi‑Fi నెట్వర్క్కు కనెక్ట్ చేయబడింది"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"మీరు <xliff:g id="NAME">%s</xliff:g> మీకోసం సూచించే నెట్వర్క్లకు అనుమతిస్తారా?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"మీరు అధిక నాణ్యత గల సేవ్ చేసిన నెట్వర్క్కు సమీపంగా ఉన్నప్పుడు"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"తిరిగి ఆన్ చేయవద్దు"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 9ce29302b016..2edf57c8a9d4 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"อนุญาตให้แอปพลิเคชันเข้าถึงฟีเจอร์โทรศัพท์ของอุปกรณ์ การอนุญาตนี้ทำให้แอปพลิเคชันสามารถตรวจสอบหมายเลขโทรศัพท์และรหัสอุปกรณ์ ตรวจสอบว่ามีการโทรที่ทำงานอยู่หรือไม่ และตรวจสอบหมายเลขระยะไกลที่เชื่อมต่อด้วยการโทร"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"กำหนดเส้นทางการโทรผ่านระบบ"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"อนุญาตให้แอปกำหนดเส้นทางการโทรของแอปผ่านระบบเพื่อปรับปรุงประสบการณ์ในการโทร"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"ดูและจัดการการติดต่อผ่านระบบ"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"อนุญาตให้แอปดูและจัดการการติดต่อในอุปกรณ์ ซึ่งรวมถึงข้อมูลอย่างเช่น หมายเลขที่ใช้ในการติดต่อและสถานะการติดต่อ"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ต่อสายจากแอปอื่น"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"อนุญาตให้แอปต่อสายที่เริ่มจากแอปอื่น"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"อ่านหมายเลขโทรศัพท์"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"อนุญาตให้แอปพลิเคชันสื่อสารกับแท็ก Near Field Communication (NFC) การ์ด และโปรแกรมอ่าน"</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ปิดใช้งานการล็อกหน้าจอของคุณ"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"อนุญาตให้แอปพลิเคชันปิดใช้งานการล็อกปุ่มกดและการรักษาความปลอดภัยด้วยรหัสผ่านใดๆ ที่เกี่ยวข้อง ตัวอย่างเช่น โทรศัพท์ปิดใช้งานการล็อกปุ่มกดเมื่อรับสายเรียกเข้า จากนั้นจึงเปิดใช้งานการล็อกปุ่มกดใหม่หลังจากวางสาย"</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ใช้และขอดูความซับซ้อนของ \"ล็อกหน้าจอ\""</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"อนุญาตให้แอปเรียนรู้ระดับความซับซ้อนของการล็อกหน้าจอ (สูง ปานกลาง ต่ำ หรือไม่มี) ซึ่งแสดงให้เห็นช่วงความยาวและประเภทของการล็อกหน้าจอที่เป็นไปได้ นอกจากนี้แอปยังแนะนำให้ผู้ใช้อัปเดตการล็อกหน้าจอเป็นระดับหนึ่งๆ ได้ด้วย แต่ผู้ใช้จะปฏิเสธและไปยังส่วนต่างๆ ต่อได้ โปรดทราบว่าระบบไม่ได้จัดเก็บการล็อกหน้าจอไว้เป็นข้อความธรรมดา เพื่อให้แอปไม่รู้รหัสผ่าน"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"ใช้ฮาร์ดแวร์ชีวมิติ"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"อนุญาตให้แอปใช้ฮาร์ดแวร์ชีวมิติเพื่อตรวจสอบสิทธิ์"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"จัดการฮาร์ดแวร์ลายนิ้วมือ"</string> @@ -1097,14 +1101,14 @@ <string name="add_contact_desc" msgid="4830217847004590345">"เพิ่มในรายชื่อติดต่อ"</string> <string name="view_calendar" msgid="979609872939597838">"ดู"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"ดูเวลาที่เลือกในปฏิทิน"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"กำหนดการ"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"ตั้งเวลา"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"ตั้งเวลากิจกรรมสำหรับเวลาที่เลือก"</string> - <string name="view_flight" msgid="7691640491425680214">"แทร็ก"</string> + <string name="view_flight" msgid="7691640491425680214">"ติดตาม"</string> <string name="view_flight_desc" msgid="3876322502674253506">"ติดตามเที่ยวบินที่เลือก"</string> <string name="translate" msgid="9218619809342576858">"แปล"</string> <string name="translate_desc" msgid="4502367770068777202">"แปลข้อความที่เลือก"</string> <string name="define" msgid="7394820043869954211">"หาความหมาย"</string> - <string name="define_desc" msgid="7910883642444919726">"ให้คำจำกัดความข้อความที่เลือก"</string> + <string name="define_desc" msgid="7910883642444919726">"หาความหมายข้อความที่เลือก"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"พื้นที่จัดเก็บเหลือน้อย"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"บางฟังก์ชันระบบอาจไม่ทำงาน"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"พื้นที่เก็บข้อมูลไม่เพียงพอสำหรับระบบ โปรดตรวจสอบว่าคุณมีพื้นที่ว่าง 250 MB แล้วรีสตาร์ท"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"แท็บเล็ตกำลังอัปเดต…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"อุปกรณ์กำลังอัปเดต…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"โทรศัพท์กำลังเริ่มต้น…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android กำลังเริ่มต้น…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"แท็บเล็ตกำลังเริ่มต้น…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"อุปกรณ์กำลังเริ่มต้น…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"กำลังเพิ่มประสิทธิภาพพื้นที่จัดเก็บข้อมูล"</string> @@ -1239,6 +1244,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="1524719325616630906">"เชื่อมต่ออยู่กับเครือข่าย Wi‑Fi ที่ <xliff:g id="NAME">%s</xliff:g> แนะนำ"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"ต้องการให้ <xliff:g id="NAME">%s</xliff:g> แนะนำเครือข่ายให้ไหม"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"เมื่อคุณอยู่ใกล้เครือข่ายคุณภาพสูงที่บันทึกไว้"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ไม่ต้องเปิดอีกครั้ง"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 11936257eb9c..f7995f77d3e4 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Pinapayagan ang app na i-access ang mga tampok ng telepono ng device. Pinapayagan ng pahintulot na ito ang app na tukuyin ang numero ng telepono at mga ID ng device, kung aktibo man ang isang tawag, at ang malayuang numerong ikinonekta ng isang tawag."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"iruta ang mga tawag sa pamamagitan ng system"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Pinapayagan ang app na iruta ang mga tawag nito sa pamamagitan ng system upang mapahusay ang karanasan sa pagtawag."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"tingnan at kontrolin ang mga tawag sa pamamagitan ng system."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Binibigyang-daan ang app na makita at makontrol ang mga kasalukuyang tawag sa device. Kabilang dito ang impormasyon gaya ng mga numero ng tawag para sa mga tawag at ang status ng mga tawag."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"ipagpatuloy ang isang tawag mula sa ibang app"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Pinapayagan ang app na ipagpatuloy ang isang tawag na sinimulan sa ibang app."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"basahin ang mga numero ng telepono"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Pinapayagan ang app na makipag-ugnay sa Near Field Communication (NFC) na mga tag, card, at reader."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"i-disable ang iyong screen lock"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Pinapayagan ang app na i-disable ang keylock at anumang nauugnay na seguridad sa password. Halimbawa, hindi pinapagana ng telepono ang keylock kapag nakakatanggap ng papasok na tawag sa telepono, pagkatapos ay muling pinapagana ang keylock kapag tapos na ang tawag."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"kunin at humiling ng pagiging kumplikado ng lock ng screen"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Pinapayagan ang app na malaman ang antas ng pagiging kumplikado ng lock ng screen (mataas, katamtaman, mababa, o wala), na nagsasaad ng posibleng hanay ng haba at uri ng lock ng screen. Maaari ding magmungkahi ang app sa mga user na i-update nila ang lock ng screen sa isang partikular na antas ngunit malaya ang mga user na balewalain ito at mag-navigate palayo. Tandaang hindi naka-store bilang plaintext ang lock ng screen kaya hindi alam ng app ang eksaktong password."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"gumamit ng biometric hardware"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Pinapayagan ang app na gumamit ng biometric hardware para sa pag-authenticate"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"pamahalaan ang hardware ng fingerprint"</string> @@ -1085,13 +1089,13 @@ <string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string> <string name="email" msgid="4560673117055050403">"Mag-email"</string> <string name="email_desc" msgid="3638665569546416795">"Mag-email sa mga piniling address"</string> - <string name="dial" msgid="1253998302767701559">"Tawagan"</string> + <string name="dial" msgid="1253998302767701559">"Tumawag"</string> <string name="dial_desc" msgid="6573723404985517250">"Tawagan ang piniling numero ng telepono"</string> - <string name="map" msgid="5441053548030107189">"Mapa"</string> + <string name="map" msgid="5441053548030107189">"Mag-mapa"</string> <string name="map_desc" msgid="1836995341943772348">"Hanapin ang piniling address"</string> <string name="browse" msgid="1245903488306147205">"Buksan"</string> <string name="browse_desc" msgid="8220976549618935044">"Buksan ang piniling URL"</string> - <string name="sms" msgid="4560537514610063430">"Padalhan ng Mensahe"</string> + <string name="sms" msgid="4560537514610063430">"Magmensahe"</string> <string name="sms_desc" msgid="7526588350969638809">"Padalhan ng mensahe ang piniling numero ng telepono"</string> <string name="add_contact" msgid="7867066569670597203">"Magdagdag"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Idagdag sa mga contact"</string> @@ -1101,8 +1105,8 @@ <string name="add_calendar_event_desc" msgid="4326891793260687388">"Mag-iskedyul ng event para sa piniling oras"</string> <string name="view_flight" msgid="7691640491425680214">"Subaybayan"</string> <string name="view_flight_desc" msgid="3876322502674253506">"I-track ang piniling flight"</string> - <string name="translate" msgid="9218619809342576858">"Isalin"</string> - <string name="translate_desc" msgid="4502367770068777202">"Isalin ang napiling text"</string> + <string name="translate" msgid="9218619809342576858">"I-translate"</string> + <string name="translate_desc" msgid="4502367770068777202">"I-translate ang piniling text"</string> <string name="define" msgid="7394820043869954211">"Ilarawan"</string> <string name="define_desc" msgid="7910883642444919726">"Ilarawan ang piniling text"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nauubusan na ang puwang ng storage"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Nag-a-update ang tablet…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Nag-a-update ang device…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Nagsisimula ang telepono…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Nagsisimula ang Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Nagsisimula ang tablet…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Nagsisimula ang device…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ino-optimize ang storage."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Lahat ng network"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Nakakonekta sa Wi‑Fi network na iminungkahi ng <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Gusto mo bang hayaan ang <xliff:g id="NAME">%s</xliff:g> na magmungkahi ng mga network para sa iyo?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oo"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hindi"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Awtomatikong mag-o-on ang Wi‑Fi"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kapag malapit ka sa naka-save na network na mataas ang kalidad"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Huwag i-on muli"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 521da3f5494f..761eba6dad0f 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Uygulamaya cihazdaki telefon özelliklerine erişme izni verir. Bu izin, uygulamanın telefon numarasını ve cihaz kimliğini, etkin bir çağrı olup olmadığını ve çağrıda bağlanılan karşı tarafın numarasını öğrenmesine olanak sağlar."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"çağrıları sistem üzerinden yönlendir"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Uygulamanın, çağrı deneyimini iyileştirmek için çağrılarını sistem üzerinden yönlendirmesine olanak tanır."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"aramaları sistemde görüp denetleme."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Uygulamanın cihazda devam eden aramaları görmesini ve denetlemesini sağlar. Bu bilgiler arasında aramaların yapıldığı numaralar ve aramaların durumu gibi bilgiler yer alır."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"başka bir uygulamadaki çağrıya devam etme"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Uygulamanın, başka bir uygulamada başlatılan çağrıya devam etmesine izin verir."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"telefon numaralarını oku"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Uygulamaya, Near Field Communication (NFC) etiketleri, kartlar ve okuyucular ile iletişim kurma izni verir."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ekran kilidimi devre dışı bırak"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Uygulamaya, tuş kilidini ve ilişkili tüm şifreli güvenlik önlemlerini devre dışı bırakma izni verir. Örneğin, telefon, çağrı alındığında tuş kilidinin devre dışı bırakır ve sonra, görüşme bittiğinde kilidi yeniden etkinleştirir."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"ekran kilidi karmaşıklığını edinme ve isteme"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Uygulamanın, ekran kilidi karmaşıklık seviyesini (yüksek, orta, düşük veya yok) öğrenmesini sağlar. Ekran kilidi karmaşıklık seviyesi, ekran kilidinin olası uzunluk aralığını ve türünü gösterir. Uygulama, kullanıcılara ekran kilidini belirli bir seviyeye güncellemelerini de önerebilir, ancak kullanıcılar bunu istedikleri gibi yoksayabilir ve geçebilirler. Ekran kilidi şifrelenmemiş metin olarak saklanmadığı için uygulamanın şifreyi tam olarak bilmediğini unutmayın."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"biyometrik donanım kullan"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Uygulamanın kimlik doğrulama için biyometrik donanım kullanmasına izin verir"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"parmak izi donanımını yönetme"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Tablet güncelleniyor…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Cihaz güncelleniyor…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon başlatılıyor…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android başlatılıyor…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Tablet başlatılıyor…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Cihaz başlatılıyor…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Depolama optimize ediliyor."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tüm ağlar"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> tarafından önerilen kablosuz ağa bağlanıldı"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> uygulamasının sizin için ağ önerisinde bulunmasına izin vermek istiyor musunuz?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Evet"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hayır"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kablosuz özelliği otomatik olarak açılacak"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Daha önce kaydedilmiş yüksek kaliteli bir ağın yakınında olduğunuzda"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Tekrar açılmasın"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 2bac0c3250e7..e7e99ae73011 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -453,6 +453,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дозволяє програмі отримувати доступ до телефонних функцій пристрою. Такий дозвіл дає програмі змогу визначати номер телефону й ідентифікатори пристрою, активність виклику, а також віддалений номер, на який здійснюється виклик."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"маршрутизувати виклики через систему"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дозволяє додатку маршрутизувати виклики через систему, щоб було зручніше телефонувати."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"Переглядати виклики через систему й керувати ними."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Додаток може переглядати поточні виклики на пристрої та керувати ними. Це стосується такої інформації, як номери та стан викликів."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"продовжувати виклик з іншого додатка"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Додаток може продовжувати виклик, початий в іншому додатку."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"переглядати номери телефону"</string> @@ -513,6 +515,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Дозволяє програмі обмінюватися даними з тегами, картками та читачами екрана Near Field Communication (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"вимикати блокування екрана"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дозволяє програмі вимикати блокування клавіатури та будь-який пов’язаний паролем захист. Наприклад: телефон вимикає блокування клавіатури під час отримання вхідного дзвінка, після закінчення якого блокування клавіатури відновлюється."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"отримувати надсилати запити щодо рівня складності пароля для блокування екрана"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Дає змогу додатку визначати рівень складності пароля для блокування екрана (високий, середній, низький або нульовий), що вказує на можливий діапазон його довжини й тип. Додаток також може пропонувати користувачам підвищити рівень складності пароля для блокування екрана, але цю пропозицію можна ігнорувати. Примітка: оскільки пароль зашифрований, додаток його не знає."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"використовувати біометричне апаратне забезпечення"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Додаток може використовувати біометричне апаратне забезпечення для автентифікації"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"керувати апаратним забезпеченням для цифрових відбитків"</string> @@ -1123,15 +1127,15 @@ <string name="deleteText" msgid="6979668428458199034">"Видалити"</string> <string name="inputMethod" msgid="1653630062304567879">"Метод введення"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Дії з текстом"</string> - <string name="email" msgid="4560673117055050403">"Електронна пошта"</string> + <string name="email" msgid="4560673117055050403">"Написати лист"</string> <string name="email_desc" msgid="3638665569546416795">"Надіслати електронний лист на вибрану адресу"</string> - <string name="dial" msgid="1253998302767701559">"Зателефонувати"</string> - <string name="dial_desc" msgid="6573723404985517250">"Набрати вибраний номер телефону"</string> - <string name="map" msgid="5441053548030107189">"Карта"</string> + <string name="dial" msgid="1253998302767701559">"Телефонувати"</string> + <string name="dial_desc" msgid="6573723404985517250">"Телефонувати за вибраним номером"</string> + <string name="map" msgid="5441053548030107189">"Відкрити карту"</string> <string name="map_desc" msgid="1836995341943772348">"Знайти вибрану адресу"</string> <string name="browse" msgid="1245903488306147205">"Відкрити"</string> <string name="browse_desc" msgid="8220976549618935044">"Відкрити вибрану URL-адресу"</string> - <string name="sms" msgid="4560537514610063430">"Повідомлення"</string> + <string name="sms" msgid="4560537514610063430">"Написати SMS"</string> <string name="sms_desc" msgid="7526588350969638809">"Надіслати повідомлення за вибраним номером телефону"</string> <string name="add_contact" msgid="7867066569670597203">"Додати"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Додати в контакти"</string> @@ -1221,6 +1225,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Планшет оновлюється…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Пристрій оновлюється…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Телефон запускається…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Запуск ОС Android…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Планшет запускається…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Пристрій запускається…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимізація пам’яті."</string> @@ -1283,6 +1288,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="1524719325616630906">"Під’єднано до мережі Wi-Fi, яку запропонував додаток <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Дозволити додатку <xliff:g id="NAME">%s</xliff:g> пропонувати вам мережі?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Коли ви поблизу збереженої мережі високої якості"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не вмикати знову"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 22662215a2c6..e33f3f2f2973 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ایپ کو آلے کی فون والی خصوصیات تک رسائی حاصل کرنے کی اجازت دیتا ہے۔ یہ اجازت ایپ کو فون نمبر اور آلے کے IDs کا تعین کرنے، آیا کوئی کال فعال ہے، اور کال کے ذریعہ مربوط ریموٹ نمبر کا تعین کرنے دیتی ہے۔"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"سسٹم کے ذریعہ کالز روٹ کریں"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"کالںگ کا تجربہ بہتر بنانے کے لیے سسٹم کے ذریعہ ایپ کو کالز روٹ کرنے کی اجازت دیتا ہے۔"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"سسٹم کے ذریعے کالز دیکھیں اور کنٹرول کریں۔"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"ایپ کو آلہ پر جاری کالز دیکھنے اور کنٹرول کرنے کی اجازت دیں۔ اس میں کالز کیلئے کال نمبرز اور کالز کی حالت جیسی معلومات شامل ہیں۔"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"دوسری ایپ کی کال جاری رکھیں"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"ایپ کو دوسری ایپ میں شروع کردہ کال کو جاری رکھنے کی اجازت ملتی ہے۔"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"فون نمبرز پڑھیں"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"ایپ کو Near Field Communication (NFC) ٹیگز، کارڈز اور ریڈرز کے ساتھ مواصلت کرنے کی اجازت دیٹا ہے۔"</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"اپنے اسکرین لاک کو غیر فعال کریں"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ایپ کو کلیدی لاک اور کسی بھی متعلقہ پاس ورڈ سیکیورٹی کو غیر فعال کرنے کی اجازت دیتا ہے۔ مثلاً، کوئی آنے والی فون کال موصول ہونے کے وقت فون کلیدی لاک کو غیر فعال کرتا ہے، پھر کال پوری ہوجانے پر کلیدی لاک کو دوبارہ فعال کردیتا ہے۔"</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"موصول کریں اور اسکرین لاک کی پیچیدگی کے لیے درخواست کریں"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"اپپ کو اسکرین لاک کی پیچیدگی (مُشکل، درمیانی، آسان یا کوئی نہیں) کو جاننے کی اجازت دیتا ہے، جو لمبائی کی ممکنہ حد اور اسکرین لاک کے قسم کو بتاتا ہے۔ اپپ صارفین کو مشوره بھی دے سکتی ہے کہ وہ اسکرین لاک کو مخصوس لیول تک اپ ڈیٹ کرتے ہیں لیکن صارفین آزادانہ طور پر نظر انداز اور نیویگیٹ کر سکتے ہیں۔ یاد رکھیں کہ اسکرین لاک پلین ٹیکسٹ میں اسٹور کیا ہوا نہیں ہے اس لیے اپپ صحیح پاس ورڈ نہیں جانتی ہے۔"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"بایومیٹرک ہارڈ ویئر استعمال کریں"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"ایپ کو توثیق کے لیے بایومیٹرک ہارڈ ویئر استعمال کرنے کی اجازت دیتا ہے"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"فنگر پرنٹ ہارڈ ویئر کا نظم کریں"</string> @@ -1083,15 +1087,15 @@ <string name="deleteText" msgid="6979668428458199034">"حذف کریں"</string> <string name="inputMethod" msgid="1653630062304567879">"اندراج کا طریقہ"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"متن کی کارروائیاں"</string> - <string name="email" msgid="4560673117055050403">"ای میل"</string> + <string name="email" msgid="4560673117055050403">"ای میل بھیجیں"</string> <string name="email_desc" msgid="3638665569546416795">"منتخب کردہ پتہ پر ای میل کریں"</string> <string name="dial" msgid="1253998302767701559">"کال کریں"</string> <string name="dial_desc" msgid="6573723404985517250">"منتخب کردہ فون نمبر پر کال کریں"</string> - <string name="map" msgid="5441053548030107189">"نقشہ"</string> + <string name="map" msgid="5441053548030107189">"نقشہ کی ایپ کھولیں"</string> <string name="map_desc" msgid="1836995341943772348">"منتخب کردہ پتہ تلاش کریں"</string> <string name="browse" msgid="1245903488306147205">"کھولیں"</string> <string name="browse_desc" msgid="8220976549618935044">"منتخب کردہ URL کھولیں"</string> - <string name="sms" msgid="4560537514610063430">"پیغام"</string> + <string name="sms" msgid="4560537514610063430">"پیغام بھیجیں"</string> <string name="sms_desc" msgid="7526588350969638809">"منتخب کردہ فون نمبر پر پیغام بھیجیں"</string> <string name="add_contact" msgid="7867066569670597203">"شامل کریں"</string> <string name="add_contact_desc" msgid="4830217847004590345">"رابطوں میں شامل کریں"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"ٹیبلٹ اپ ڈیٹ ہو رہا ہے…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"آلہ اپ ڈیٹ ہو رہا ہے…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"فون شروع ہو رہا ہے…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android شروع ہو رہا ہے…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"ٹیبلیٹ شروع ہو رہا ہے…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"آلہ شروع ہو رہا ہے…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"اسٹوریج کو بہترین بنایا جا رہا ہے۔"</string> @@ -1239,6 +1244,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="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> کے ذریعے تجویز کردہ Wi-Fi نیٹ ورک سے منسلک کر دیا گیا"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"کیا آپ <xliff:g id="NAME">%s</xliff:g> کو آپ کے لیے نیٹ ورکس تجویز کرنے کی اجازت دینا چاہتے ہیں؟"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"جب آپ اعلی معیار کے محفوظ کردہ نیٹ ورک کے قریب ہوں"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"دوبارہ آن نہ کریں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 204df4e937aa..7742c3e6b59b 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ilovaga qurilmangizdagi telefon xususiyatlariga kirishga ruxsat beradi. Bu ruxsat ilovaga telefon raqami va qurilma nomlari, qo‘ng‘iroq faol yoki faolsizligi va masofadagi raqam qo‘ng‘rioq orqali bog‘langanligini aniqlashga imkon beradi."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"chaqiruvlarni tizim orqali yo‘naltirish"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Ilova aloqa sifatini yaxshilash maqsadida chaqiruvlarni tizim orqali yo‘naltirishi mumkin."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"tizim orqali chaqiruvlarni tekshirish va boshqarish."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Ilovaga qurilmadagi amaldagi chaqiruvlarni tekshirish va boshqarish imkonini beradi. Shuningdek, chaqiruvlar holati va kiruvchi-chiquvchi chaqiruv raqamlari axborotiga ham ruxsat beradi."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"chaqiruvni boshqa ilovada davom ettirish"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Ilovaga boshqa ilovada boshlangan chaqiruvni davom ettirish imkon beradi"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"telefon raqamlarini o‘qish"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Ilova qisqa masofali aloqa (NFC) texnologiyasi yordamida NFC yorliqlari, kartalar va o‘qish moslamalari bilan ma’lumot almashishi mumkin."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ekran qulfini o‘chirib qo‘yish"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ilovaga ekran qulfini va har qanday parol yordamidagi xavfsizlik himoyalarini o‘chirishga ruxsat beradi. Masalan, kirish qo‘ng‘irog‘ida telefon ekran qulfini o‘chiradi va qo‘ng‘iroq tugashi bilan qulfni yoqadi."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"Ekran qulfining qiyinlik darajasini oshirish haqidagi axborotga ruxsat va tavsiyalar berish"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Ilova ekran qulfining qiyinlik darajasi (yuqori, oʻrta, past yoki hech qanday), jumladan, qulf turi va parol uzunligi haqida axborotga ruxsat oladi. Bundan tashqari, foydalanuvchilarga qulflash qiyinligi darajasini oshirish taklif etiladi. Bu tavsiyalar majburiy emas. Parollar ochiq matn sifatida saqlanmaydi va ilova uni ocha olmaydi."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrik sensordan foydalanish"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Haqiqiylikni tekshirish uchun biometrik sensordan foydalanish imkonini beradi"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"barmoq izi skanerini boshqarish"</string> @@ -1084,22 +1088,22 @@ <string name="inputMethod" msgid="1653630062304567879">"Kiritish uslubi"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Matn yozish"</string> <string name="email" msgid="4560673117055050403">"E-pochta"</string> - <string name="email_desc" msgid="3638665569546416795">"Belgilangan manzilga xat yuborish"</string> + <string name="email_desc" msgid="3638665569546416795">"Belgilangan e-pochta manziliga xat yuborish"</string> <string name="dial" msgid="1253998302767701559">"Chaqiruv"</string> <string name="dial_desc" msgid="6573723404985517250">"Belgilangan raqamga telefon qilish"</string> <string name="map" msgid="5441053548030107189">"Xarita"</string> <string name="map_desc" msgid="1836995341943772348">"Belgilangan manzilni xaritadan topish"</string> <string name="browse" msgid="1245903488306147205">"Ochish"</string> <string name="browse_desc" msgid="8220976549618935044">"Belgilangan URL manzilini ochish"</string> - <string name="sms" msgid="4560537514610063430">"Xabar"</string> + <string name="sms" msgid="4560537514610063430">"SMS yozish"</string> <string name="sms_desc" msgid="7526588350969638809">"Belgilangan telefon raqamiga SMS yuborish"</string> - <string name="add_contact" msgid="7867066569670597203">"Qo‘shish"</string> + <string name="add_contact" msgid="7867066569670597203">"Saqlab olish"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Kontaktlarga saqlash"</string> <string name="view_calendar" msgid="979609872939597838">"Ochish"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"Taqvimda belgilangan vaqtni ko‘rish"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Jadval"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"Belgilangan vaqt uchun tadbirni rejalashtirish"</string> - <string name="view_flight" msgid="7691640491425680214">"Trek"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"Belgilangan vaqtni taqvimda ochish"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Rejalashtirish"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"Belgilangan vaqt uchun tadbir rejalashtirish"</string> + <string name="view_flight" msgid="7691640491425680214">"Kuzatish"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Belgilangan parvozni kuzatish"</string> <string name="translate" msgid="9218619809342576858">"Tarjima qilish"</string> <string name="translate_desc" msgid="4502367770068777202">"Belgilangan matnni tarjima qilish"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Planshet yangilanmoqda…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Qurilma yangilanmoqda…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Telefon ishga tushirilmoqda…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android ishga tushmoqda…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Planshet ishga tushirilmoqda…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Qurilma ishga tushirilmoqda…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Xotira optimallashtirilmoqda."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Barcha tarmoqlar"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"<xliff:g id="NAME">%s</xliff:g> ilovasi topgan Wi-Fi tarmoqqa ulanildi"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"<xliff:g id="NAME">%s</xliff:g> ilovasi sizga tarmoq taklif etishi uchun unga ruxsat berilsinmi?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ha"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Yoʻq"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik ravishda yoqiladi"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Saqlangan tarmoqlar ichidan signali yaxshisi hududida ekaningizda"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Qayta yoqilmasin"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 70f3161ddcbc..86bb532f8e6c 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Cho phép ứng dụng truy cập vào các tính năng điện thoại của thiết bị. Quyền này cho phép ứng dụng xác định số điện thoại và ID thiết bị, cho dù cuộc gọi có hiện hoạt hay không và số từ xa có được kết nối bằng một cuộc gọi hay không."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"định tuyến cuộc gọi thông qua hệ thống"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Cho phép ứng dụng định tuyến cuộc gọi thông qua hệ thống nhằm cải thiện trải nghiệm gọi điện."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"xem và kiểm soát cuộc gọi thông qua hệ thống."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Cho phép ứng dụng xem và kiểm soát cuộc gọi đến trên thiết bị. Ứng dụng sẽ xem và kiểm soát các thông tin như số điện thoại của các cuộc gọi và trạng thái cuộc gọi."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"tiếp tục cuộc gọi từ một ứng dụng khác"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Cho phép ứng dụng tiếp tục cuộc gọi được bắt đầu trong một ứng dụng khác."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"đọc số điện thoại"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"nhận và yêu cầu độ phức tạp của khóa màn hình"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Cho phép ứng dụng nắm được 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ó), 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ể đề xuất cho người dùng rằng họ 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, do đó, ứng dụng sẽ không biết mật khẩu chính xác."</string> <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> @@ -1083,22 +1087,22 @@ <string name="deleteText" msgid="6979668428458199034">"Xóa"</string> <string name="inputMethod" msgid="1653630062304567879">"Phương thức nhập"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Tác vụ văn bản"</string> - <string name="email" msgid="4560673117055050403">"Email"</string> + <string name="email" msgid="4560673117055050403">"Gửi email"</string> <string name="email_desc" msgid="3638665569546416795">"Gửi email đến địa chỉ đã chọn"</string> - <string name="dial" msgid="1253998302767701559">"Gọi"</string> + <string name="dial" msgid="1253998302767701559">"Gọi điện"</string> <string name="dial_desc" msgid="6573723404985517250">"Gọi đến số điện thoại đã chọn"</string> - <string name="map" msgid="5441053548030107189">"Bản đồ"</string> + <string name="map" msgid="5441053548030107189">"Xem bản đồ"</string> <string name="map_desc" msgid="1836995341943772348">"Tìm địa chỉ đã chọn"</string> <string name="browse" msgid="1245903488306147205">"Mở"</string> <string name="browse_desc" msgid="8220976549618935044">"Mở URL đã chọn"</string> - <string name="sms" msgid="4560537514610063430">"Gửi tin nhắn"</string> + <string name="sms" msgid="4560537514610063430">"Nhắn tin"</string> <string name="sms_desc" msgid="7526588350969638809">"Nhắn tin đến số điện thoại đã chọn"</string> <string name="add_contact" msgid="7867066569670597203">"Thêm"</string> <string name="add_contact_desc" msgid="4830217847004590345">"Thêm vào danh bạ"</string> <string name="view_calendar" msgid="979609872939597838">"Xem"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Xem thời gian đã chọn trong lịch"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Lịch biểu"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"Lên lịch biểu sự kiện cho thời gian đã chọn"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Lên lịch"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"Lên lịch sự kiện cho thời gian đã chọn"</string> <string name="view_flight" msgid="7691640491425680214">"Theo dõi"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Theo dõi chuyến bay đã chọn"</string> <string name="translate" msgid="9218619809342576858">"Dịch"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Máy tính bảng đang cập nhật…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Thiết bị đang cập nhật…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Điện thoại đang khởi động…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android đang khởi động..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Máy tính bảng đang khởi động…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Thiết bị đang khởi động…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Tối ưu hóa lưu trữ."</string> @@ -1239,6 +1244,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="1524719325616630906">"Đã 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="4505530604935334589">"Bạn có muốn cho phép <xliff:g id="NAME">%s</xliff:g> đề xuất mạng cho bạn không?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Khi bạn ở gần mạng đã lưu chất lượng cao"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Không bật lại"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index c38406f2bbcd..dbb7834d1843 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允许该应用访问设备的电话功能。此权限可让该应用确定本机号码和设备 ID、是否正处于通话状态以及拨打的号码。"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"通过系统转接来电"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"允许该应用通过系统转接来电,以改善通话体验。"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"查看并控制通过系统拨打的电话。"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"允许应用查看并控制设备上正在进行的通话,其中包括通话号码和通话状态等信息。"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"继续进行来自其他应用的通话"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"允许该应用继续进行在其他应用中发起的通话。"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"读取电话号码"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"获取和请求屏幕锁定复杂度"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"允许应用了解屏幕锁定复杂度(高、中、低或无),即屏幕锁定的可能长度范围和类型。应用还可以建议用户将屏幕锁定更新为特定复杂度,但用户可以随意选择忽略该建议并离开。请注意,系统不会以纯文字形式存储屏幕锁定选项的内容,因此应用不会知道确切密码。"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"使用生物特征硬件"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"允许该应用使用生物特征硬件进行身份验证"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"管理指纹硬件"</string> @@ -1083,11 +1087,11 @@ <string name="deleteText" msgid="6979668428458199034">"删除"</string> <string name="inputMethod" msgid="1653630062304567879">"输入法"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string> - <string name="email" msgid="4560673117055050403">"电子邮件"</string> + <string name="email" msgid="4560673117055050403">"发送电子邮件"</string> <string name="email_desc" msgid="3638665569546416795">"将电子邮件发送至所选地址"</string> <string name="dial" msgid="1253998302767701559">"拨打电话"</string> <string name="dial_desc" msgid="6573723404985517250">"拨打所选电话号码"</string> - <string name="map" msgid="5441053548030107189">"地图"</string> + <string name="map" msgid="5441053548030107189">"查看地图"</string> <string name="map_desc" msgid="1836995341943772348">"找到所选地址"</string> <string name="browse" msgid="1245903488306147205">"打开"</string> <string name="browse_desc" msgid="8220976549618935044">"打开所选网址"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"平板电脑正在更新…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"设备正在更新…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"手机正在启动…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android 正在启动…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"平板电脑正在启动…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"设备正在启动…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在优化存储空间。"</string> @@ -1239,6 +1244,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="1524719325616630906">"已连接到<xliff:g id="NAME">%s</xliff:g>建议的 WLAN 网络"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"要让<xliff:g id="NAME">%s</xliff:g>为您建议网络吗?"</string> + <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">"WLAN 将自动开启"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"当您位于已保存的高品质网络信号范围内时"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新开启"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index f59cfcb427a1..6248db5be4b8 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限允許應用程式確定手機號碼和裝置編號、是否正在通話中,以及所撥打的對方號碼。"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"透過系統轉接來電"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"允許應用程式透過系統轉接來電,以改善通話體驗。"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"透過系統查看和控制通話。"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"允許應用程式查看和控制裝置上正在進行的通話,當中包括通話號碼和通話狀態等資訊。"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"繼續進行來自其他應用程式的通話"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"允許應用程式繼續進行在其他應用程式中開始的通話。"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"讀取電話號碼"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"獲取並要求螢幕鎖定複雜程度"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"允許應用程式瞭解螢幕鎖定的複雜程度 (高、中、低或無),這項資料說明了螢幕鎖定的可能長度範圍和類型。應用程式亦能建議使用者將螢幕鎖定更新至某個複雜程度,但使用者可以隨意忽略並離開。請注意,螢幕鎖定並非以純文字儲存,因此應用程式不知道確切的密碼。"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"使用生物識別硬件"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"允許應用程式使用生物識別硬件驗證"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"管理指紋硬件"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"正在更新平板電腦…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"正在更新裝置…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"手機正在啟動…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android 正在啟動…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"平板電腦正在啟動…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"裝置正在啟動…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在優化儲存空間。"</string> @@ -1239,6 +1244,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="1524719325616630906">"已連接至「<xliff:g id="NAME">%s</xliff:g>」建議的 Wi‑Fi 網絡"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"您希望「<xliff:g id="NAME">%s</xliff:g>」為您建議網絡嗎?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"當您位於已儲存的高品質網絡信號範圍內時"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新開啟"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 489dfead4b7c..74da200597ec 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限可讓應用程式判讀手機號碼和裝置 ID、是否正在通話中,以及所撥打的對方號碼。"</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"透過系統接通來電"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"允許應用程式透過系統接通來電,以改善通話品質。"</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"查看及控管透過系統撥打的電話。"</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"允許應用程式查看及控管在裝置上撥出的電話,包括撥打的電話號碼和通話狀態等資訊。"</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"繼續進行來自其他應用程式的通話"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"允許應用程式繼續進行在其他應用程式中發起的通話。"</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"讀取電話號碼"</string> @@ -507,6 +509,8 @@ <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_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"取得及要求螢幕鎖定複雜度"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"允許應用程式記住螢幕鎖定的複雜度 (高、中、低或無),即螢幕鎖定的可能長度範圍和類型。這樣一來,應用程式還能建議使用者將螢幕鎖定更新為特定複雜度,但使用者可選擇忽略建議並離開應用程式。請注意,系統不會以純文字格式儲存螢幕鎖定選項的內容,因此應用程式不會知道確切密碼。"</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"使用生物特徵硬體"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"允許應用程式使用生物特徵硬體進行驗證"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"管理指紋硬體"</string> @@ -1083,28 +1087,28 @@ <string name="deleteText" msgid="6979668428458199034">"刪除"</string> <string name="inputMethod" msgid="1653630062304567879">"輸入法"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"文字動作"</string> - <string name="email" msgid="4560673117055050403">"電子郵件"</string> - <string name="email_desc" msgid="3638665569546416795">"將電子郵件寄到所選地址"</string> - <string name="dial" msgid="1253998302767701559">"通話"</string> - <string name="dial_desc" msgid="6573723404985517250">"撥打所選電話號碼"</string> - <string name="map" msgid="5441053548030107189">"地圖"</string> - <string name="map_desc" msgid="1836995341943772348">"尋找所選地址"</string> + <string name="email" msgid="4560673117055050403">"發送電子郵件"</string> + <string name="email_desc" msgid="3638665569546416795">"將電子郵件寄到選取的地址"</string> + <string name="dial" msgid="1253998302767701559">"撥號通話"</string> + <string name="dial_desc" msgid="6573723404985517250">"撥打選取的電話號碼"</string> + <string name="map" msgid="5441053548030107189">"查看地圖"</string> + <string name="map_desc" msgid="1836995341943772348">"尋找選取的地址"</string> <string name="browse" msgid="1245903488306147205">"開啟"</string> - <string name="browse_desc" msgid="8220976549618935044">"開啟所選網址"</string> - <string name="sms" msgid="4560537514610063430">"訊息"</string> - <string name="sms_desc" msgid="7526588350969638809">"將訊息傳送到所選電話號碼"</string> + <string name="browse_desc" msgid="8220976549618935044">"開啟選取的網址"</string> + <string name="sms" msgid="4560537514610063430">"發送訊息"</string> + <string name="sms_desc" msgid="7526588350969638809">"將訊息傳送到選取的電話號碼"</string> <string name="add_contact" msgid="7867066569670597203">"新增"</string> <string name="add_contact_desc" msgid="4830217847004590345">"新增至聯絡人"</string> <string name="view_calendar" msgid="979609872939597838">"查看"</string> - <string name="view_calendar_desc" msgid="5828320291870344584">"在日曆中查看所選時間"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"時間表"</string> - <string name="add_calendar_event_desc" msgid="4326891793260687388">"將活動安排在所選時間"</string> + <string name="view_calendar_desc" msgid="5828320291870344584">"在日曆中查看選取的時間"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"加入日曆"</string> + <string name="add_calendar_event_desc" msgid="4326891793260687388">"將活動安排在選取的時間"</string> <string name="view_flight" msgid="7691640491425680214">"追蹤"</string> - <string name="view_flight_desc" msgid="3876322502674253506">"追蹤所選航班"</string> + <string name="view_flight_desc" msgid="3876322502674253506">"追蹤選取的航班"</string> <string name="translate" msgid="9218619809342576858">"翻譯"</string> - <string name="translate_desc" msgid="4502367770068777202">"翻譯所選文字"</string> - <string name="define" msgid="7394820043869954211">"定義"</string> - <string name="define_desc" msgid="7910883642444919726">"定義所選文字"</string> + <string name="translate_desc" msgid="4502367770068777202">"翻譯選取的文字"</string> + <string name="define" msgid="7394820043869954211">"查看定義"</string> + <string name="define_desc" msgid="7910883642444919726">"定義選取的文字"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"系統儲存空間不足。請確定你已釋出 250MB 的可用空間,然後重新啟動。"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"平板電腦正在更新…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"裝置正在更新…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"手機正在啟動…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Android 正在啟動…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"平板電腦正在啟動…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"裝置正在啟動…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在對儲存空間進行最佳化處理。"</string> @@ -1239,6 +1244,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="1524719325616630906">"已連上「<xliff:g id="NAME">%s</xliff:g>」建議使用的 Wi-Fi 網路"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"是否要允許「<xliff:g id="NAME">%s</xliff:g>」為你建議網路?"</string> + <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> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"當你位於已儲存的高品質網路範圍內時"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新開啟"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 18a3db42d879..93b2ae6f8e79 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -447,6 +447,8 @@ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ivumela uhlelo lokusebenza ukufinyelela izici zefoni zedivayisi. Le mvume ivumela uhlelo lokusebenza ukucacisa inombolo yefoni nobunikazi bedivayisi, ukuthi noma ikholi iyasebenza, futhi nenombolo yesilawuli kude zixhunywe ngekholi."</string> <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"yanza imizila yamakholi ngesistimu"</string> <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Ivumela uhlelo lokusebenza ukwenza imizila yamakholi ngesistimu ukuze ithuthukise umuzwa wokushaya."</string> + <string name="permlab_callCompanionApp" msgid="3599252979411970473">"bona futhi ulawule amakholi ngesistimu."</string> + <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Ivumela uhlelo lokusebenza ukubona nokulawula amakholi aqhubekayo kudivayisi. Lokhu kubandakanya ulwazi olufana nezinombolo zamakholi nesimo samakholi."</string> <string name="permlab_acceptHandover" msgid="2661534649736022409">"qhuba ikholi kusukela kolunye uhlelo lokusebenza"</string> <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Ivumela uhlelo lokusebenza ukuze luqhube ikholi eqalwe kolunye uhlelo lokusebenza."</string> <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"funda izinombolo zefoni"</string> @@ -507,6 +509,8 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Ivuela uhlelo lokusebenza ukuthi ixhumane ne-Near Field Communication (NFC) amathegi, amakhadi kanye nezinhlelo zokufunda."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"khubaza ukukhiya kwakho iskrini"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ivumela uhlelo lokusebenza ukukhubaza ukuvala ukhiye nanoma yikuphi ukuphepha kwephasiwedi okuhlobene. Isibonelo, ifoni ikhubaza ukuvala ukhiye lapho ithola ikholi yefoni engenayo, bese inike amandla kabusha ukuvala ukhiye lapho ikholi isiqedile."</string> + <string name="permlab_getAndRequestScreenLockComplexity" msgid="3911592334192005424">"thola futhi ucele ukukhiywa kwesikrini"</string> + <string name="permdesc_getAndRequestScreenLockComplexity" msgid="9045202063228854873">"Ivumela uhlelo lokusebenza ukufunda ileveli yokukhiywa kwesikrini (phezulu, phakathi, phansi noma lutho), okubonisa ibanga elinokwenzeka lobubanzi nohlobo lokukhiywa kwesikrini. Uhlelo lokusebenza futhi lingaphakamisa kubasebenzisi ukuthi babuyekeze ukukhiywa kwesikrini kuya kwenye ileveli kodwa abasebenzisi bangaziba kalula bese bazule. Qaphela ukuthi ukhiywa kwesikrini akulondoloziwe embalweni ocacile ukuze uhlelo lokusebenza lingazi iphasiwedi."</string> <string name="permlab_useBiometric" msgid="8837753668509919318">"sebenzisa izingxenyekazi zekhompyutha ze-biometric"</string> <string name="permdesc_useBiometric" msgid="8389855232721612926">"Ivumela uhlelo lokusebenza ukuthi lusebenzise izingxenyekazi zekhompyutha ze-biometric ukuze kuqinisekiswe"</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"phatha izingxenyekazi zekhompyutha zezigxivizo zeminwe"</string> @@ -1097,7 +1101,7 @@ <string name="add_contact_desc" msgid="4830217847004590345">"Engeza koxhumana nabo"</string> <string name="view_calendar" msgid="979609872939597838">"Buka"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Buka isikhathi esikhethiwe kwikhalenda"</string> - <string name="add_calendar_event" msgid="1953664627192056206">"Ishejuli"</string> + <string name="add_calendar_event" msgid="1953664627192056206">"Shejula"</string> <string name="add_calendar_event_desc" msgid="4326891793260687388">"Shejula imicimbi yesikhathi esikhethiwe"</string> <string name="view_flight" msgid="7691640491425680214">"Landelela"</string> <string name="view_flight_desc" msgid="3876322502674253506">"Ithrekhi ikhethe indiza"</string> @@ -1181,6 +1185,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Ithebulethi iyabuyekeza…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Idivayisi iyabuyekeza…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Ifoni iyaqala…"</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"I-Android iyaqala…"</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Ithebulethi iyaqala…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Idivayisi iyaqala…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ikhulisa isitoreji."</string> @@ -1239,6 +1244,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Onke amanethiwekhi"</string> + <string name="wifi_suggestion_title" msgid="1524719325616630906">"Kuxhumeke kunethiwekhi ye-Wi‑Fi ephakanyiswe ngu-<xliff:g id="NAME">%s</xliff:g>"</string> + <string name="wifi_suggestion_content" msgid="4505530604935334589">"Ingabe ufuna ukuvumela i-<xliff:g id="NAME">%s</xliff:g> iphakamisa amanethiwkehi kuwe?"</string> + <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yebo"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Cha"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"I-Wi-Fi izovuleka ngokuzenzakalela"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Uma useduze kwenethiwekhi yekhwalithi ephezulu elondoloziwe"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ungaphindi uvule"</string> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index dd51cb615d8a..54f6c632907f 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1112,6 +1112,11 @@ resource] to be present in order to function. Default value is false. --> <attr name="isSplitRequired" format="boolean" /> + <!-- Flag to specify if this app prioritizes code integrity. The system may choose + to run with better integrity guarantee in various components if possible based on the app's + <code>targetSdkVersion</code>. --> + <attr name="preferCodeIntegrity" format="boolean" /> + <!-- Extra options for an activity's UI. Applies to either the {@code <activity>} or {@code <application>} tag. If specified on the {@code <application>} tag these will be considered defaults for all activities in the @@ -1580,6 +1585,7 @@ to honor this flag as well. --> <attr name="usesCleartextTraffic" /> <attr name="multiArch" /> + <attr name="preferCodeIntegrity" /> <attr name="extractNativeLibs" /> <attr name="defaultToDeviceProtectedStorage" format="boolean" /> <attr name="directBootAware" /> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9f5eab557026..e4abf8f4cf49 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -929,6 +929,9 @@ in hardware. --> <bool name="config_setColorTransformAccelerated">false</bool> + <!-- Boolean indicating whether display white balance is supported. --> + <bool name="config_displayWhiteBalanceAvailable">false</bool> + <!-- Control whether Night display is available. This should only be enabled on devices that have a HWC implementation that can apply the matrix passed to setColorTransform without impacting power, performance, and app compatibility (e.g. protected content). --> @@ -2160,9 +2163,6 @@ <!-- If the sensor that wakes up the lock screen is available or not. --> <bool name="config_dozeWakeLockScreenSensorAvailable">false</bool> - <!-- Type of the wake up sensor. Empty if not supported. --> - <string name="config_dozeWakeScreenSensorType" translatable="false"></string> - <!-- Control whether the always on display mode is available. This should only be enabled on devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND states. --> @@ -2845,19 +2845,6 @@ <bool name="config_auto_attach_data_on_creation">true</bool> - <!-- Values for GPS configuration --> - <string-array translatable="false" name="config_gpsParameters"> - <item>SUPL_HOST=supl.google.com</item> - <item>SUPL_PORT=7275</item> - <item>SUPL_VER=0x20000</item> - <item>SUPL_MODE=1</item> - <item>SUPL_ES=1</item> - <item>LPP_PROFILE=0</item> - <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>GPS_LOCK=3</item> - </string-array> - <!-- Sprint need a 70 ms delay for 3way call --> <integer name="config_cdma_3waycall_flash_delay">0</integer> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index f25427ad86fe..2b95dd088434 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3066,6 +3066,14 @@ <string name="whichViewApplicationNamed">Open with %1$s</string> <!-- Label for a link to a intent resolver dialog to view something --> <string name="whichViewApplicationLabel">Open</string> + <!-- Title of intent resolver dialog when selecting a viewer application that opens URI + [CHAR LIMIT=128]. --> + <string name="whichGiveAccessToApplication">Give access to open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with</string> + <!-- Title of intent resolver dialog when selecting a viewer application that opens URI + and a previously used application is known [CHAR LIMIT=128]. --> + <string name="whichGiveAccessToApplicationNamed">Give access to open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with <xliff:g id="application" example="Gmail">%2$s</xliff:g></string> + <!-- Label for a link to an intent resolver dialog to open URI [CHAR LIMIT=18] --> + <string name="whichGiveAccessToApplicationLabel">Give access</string> <!-- Title of intent resolver dialog when selecting an editor application to run. --> <string name="whichEditApplication">Edit with</string> <!-- Title of intent resolver dialog when selecting an editor application to run @@ -4156,6 +4164,10 @@ from the activity resolver to use just this once. [CHAR LIMIT=25] --> <string name="activity_resolver_use_once">Just once</string> + <!-- Title for a button to choose to go to + 'Open by Default' app settings. [CHAR LIMIT=25] --> + <string name="activity_resolver_app_settings">Settings</string> + <!-- Text for the toast that is shown when the user clicks on a launcher that doesn't support the work profile. [CHAR LIMIT=100] --> <string name="activity_resolver_work_profiles_support">%1$s doesn\'t support work profile</string> diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml index 7c95d1efb60d..200ef2f56f51 100644 --- a/core/res/res/values/styles_device_defaults.xml +++ b/core/res/res/values/styles_device_defaults.xml @@ -355,6 +355,30 @@ easier. <item name="fontFamily">@string/config_bodyFontFamilyMedium</item> </style> <style name="TextAppearance.DeviceDefault.Widget.Toolbar.Title" parent="TextAppearance.DeviceDefault.Widget.ActionBar.Title"/> + <style name="TextAppearance.DeviceDefault.Widget.Toolbar.Subtitle" parent="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle"/> + <style name="TextAppearance.DeviceDefault.Body1" parent="TextAppearance.Material.Body1"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Body2" parent="TextAppearance.Material.Body2"> + <item name="fontFamily">@string/config_bodyFontFamilyMedium</item> + </style> + <style name="TextAppearance.DeviceDefault.Subhead" parent="TextAppearance.Material.Subhead"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Headline" parent="TextAppearance.Material.Headline"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Display1" parent="TextAppearance.Material.Display1"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Title" parent="TextAppearance.Material.Title"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Caption" parent="TextAppearance.Material.Caption"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.ListItem" parent="TextAppearance.DeviceDefault.Subhead"/> + <style name="TextAppearance.DeviceDefault.ListItemSecondary" parent="TextAppearance.DeviceDefault.Body1"/> <!-- Preference Styles --> <style name="Preference.DeviceDefault" parent="Preference.Material"/> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 4ed050117541..e8cbf666c03c 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1269,7 +1269,6 @@ <java-symbol type="array" name="config_telephonyEuiccDeviceCapabilities" /> <java-symbol type="array" name="config_telephonyHardware" /> <java-symbol type="array" name="config_keySystemUuidMapping" /> - <java-symbol type="array" name="config_gpsParameters" /> <java-symbol type="array" name="required_apps_managed_user" /> <java-symbol type="array" name="required_apps_managed_profile" /> <java-symbol type="array" name="required_apps_managed_device" /> @@ -1369,15 +1368,6 @@ <java-symbol type="drawable" name="ic_wifi_signal_2" /> <java-symbol type="drawable" name="ic_wifi_signal_3" /> <java-symbol type="drawable" name="ic_wifi_signal_4" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_0_bars" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_1_bar" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_2_bars" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_3_bars" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_4_bars" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_4k" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_hd" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_sd" /> - <java-symbol type="drawable" name="ic_signal_wifi_badged_ld" /> <java-symbol type="drawable" name="stat_notify_rssi_in_range" /> <java-symbol type="drawable" name="stat_sys_gps_on" /> <java-symbol type="drawable" name="stat_sys_tether_wifi" /> @@ -2153,6 +2143,7 @@ <java-symbol type="id" name="resolver_list" /> <java-symbol type="id" name="button_once" /> <java-symbol type="id" name="button_always" /> + <java-symbol type="id" name="button_app_settings" /> <java-symbol type="integer" name="config_globalActionsKeyTimeout" /> <java-symbol type="integer" name="config_maxResolverActivityColumns" /> <java-symbol type="array" name="config_notificationSignalExtractors" /> @@ -2508,11 +2499,15 @@ <java-symbol type="bool" name="config_use_voip_mode_for_ims" /> <java-symbol type="attr" name="touchscreenBlocksFocus" /> <java-symbol type="layout" name="resolver_list_with_default" /> + <java-symbol type="string" name="activity_resolver_app_settings" /> <java-symbol type="string" name="whichApplicationNamed" /> <java-symbol type="string" name="whichApplicationLabel" /> <java-symbol type="string" name="whichViewApplication" /> <java-symbol type="string" name="whichViewApplicationNamed" /> <java-symbol type="string" name="whichViewApplicationLabel" /> + <java-symbol type="string" name="whichGiveAccessToApplication" /> + <java-symbol type="string" name="whichGiveAccessToApplicationNamed" /> + <java-symbol type="string" name="whichGiveAccessToApplicationLabel" /> <java-symbol type="string" name="whichEditApplication" /> <java-symbol type="string" name="whichEditApplicationNamed" /> <java-symbol type="string" name="whichEditApplicationLabel" /> @@ -3033,6 +3028,7 @@ <java-symbol type="drawable" name="ic_doc_generic" /> <java-symbol type="bool" name="config_setColorTransformAccelerated" /> + <java-symbol type="bool" name="config_displayWhiteBalanceAvailable" /> <java-symbol type="bool" name="config_nightDisplayAvailable" /> <java-symbol type="bool" name="config_allowDisablingAssistDisclosure" /> <java-symbol type="integer" name="config_defaultNightDisplayAutoMode" /> @@ -3503,7 +3499,6 @@ <java-symbol type="integer" name="db_wal_truncate_size" /> <java-symbol type="integer" name="config_wakeUpDelayDoze" /> - <java-symbol type="string" name="config_dozeWakeScreenSensorType" /> <!-- For Bluetooth AbsoluteVolume --> <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" /> diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml index 56265cc04c0c..0f4ca66dcd68 100644 --- a/core/res/res/values/themes_device_defaults.xml +++ b/core/res/res/values/themes_device_defaults.xml @@ -68,6 +68,10 @@ easier. <item name="textAppearanceLargePopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item> <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item> + <item name="textAppearanceListItem">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSmall">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSecondary">@style/TextAppearance.DeviceDefault.ListItemSecondary</item> + <!-- Button styles --> <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item> <item name="buttonStyle">@style/Widget.DeviceDefault.Button</item> @@ -783,7 +787,6 @@ easier. <!-- Text styles --> <item name="textAppearance">@style/TextAppearance.DeviceDefault</item> <item name="textAppearanceInverse">@style/TextAppearance.DeviceDefault.Inverse</item> - <item name="textAppearanceLarge">@style/TextAppearance.DeviceDefault.Large</item> <item name="textAppearanceMedium">@style/TextAppearance.DeviceDefault.Medium</item> <item name="textAppearanceSmall">@style/TextAppearance.DeviceDefault.Small</item> @@ -792,11 +795,12 @@ easier. <item name="textAppearanceSmallInverse">@style/TextAppearance.DeviceDefault.Small.Inverse</item> <item name="textAppearanceSearchResultTitle">@style/TextAppearance.DeviceDefault.SearchResult.Title</item> <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.DeviceDefault.SearchResult.Subtitle</item> - <item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item> - <item name="textAppearanceLargePopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item> <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item> + <item name="textAppearanceListItem">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSmall">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSecondary">@style/TextAppearance.DeviceDefault.ListItemSecondary</item> <!-- Button styles --> <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item> @@ -1439,19 +1443,23 @@ easier. </style> <!-- DeviceDefault theme for a window that should look like the Settings app. --> - <style name="Theme.DeviceDefault.Settings" parent="Theme.Material.Settings"> + <style name="Theme.DeviceDefault.Settings" parent="Theme.DeviceDefault.Light"> + <!-- From Theme.Material.Light.LightStatusBar --> + <item name="windowLightStatusBar">true</item> + + <!-- From Theme.Material.Settings --> + <item name="homeAsUpIndicator">@drawable/ic_ab_back_material_settings</item> + <item name="presentationTheme">@style/Theme.Material.Settings.Dialog.Presentation</item> + <item name="searchDialogTheme">@style/Theme.Material.Settings.SearchBar</item> + <item name="panelMenuListTheme">@style/Theme.Material.Settings.CompactMenu</item> + <!-- action bar --> - <item name="actionBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.Solid</item> <item name="actionBarTheme">@style/ThemeOverlay.DeviceDefault.ActionBar</item> <item name="popupTheme">@style/ThemeOverlay.DeviceDefault.Popup.Light</item> <!-- Color palette --> - <item name="colorBackground">@color/background_device_default_light</item> - <item name="colorPrimary">@color/primary_device_default_settings_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item> <item name="colorSecondary">@color/secondary_device_default_settings_light</item> - <item name="colorAccent">@color/accent_device_default_light</item> - <item name="colorError">@color/error_color_device_default_light</item> <item name="colorEdgeEffect">@android:color/black</item> <!-- Add white nav bar with divider that matches material --> @@ -1459,24 +1467,9 @@ easier. <item name="navigationBarColor">@android:color/white</item> <item name="windowLightNavigationBar">true</item> - <!-- Dialog attributes --> - <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> - <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item> - - <!-- Text styles --> - <item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item> - <!-- Button styles --> - <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item> <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item> - <!-- Progress bar attributes --> - <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item> - <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item> - - <!-- Toolbar attributes --> - <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="listDivider">@color/list_divider_color_light</item> </style> diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java index d41a718147f2..9807f26ad367 100644 --- a/core/tests/coretests/src/android/view/InsetsStateTest.java +++ b/core/tests/coretests/src/android/view/InsetsStateTest.java @@ -20,8 +20,13 @@ import static android.view.InsetsState.INSET_SIDE_BOTTOM; import static android.view.InsetsState.INSET_SIDE_TOP; import static android.view.InsetsState.TYPE_IME; import static android.view.InsetsState.TYPE_NAVIGATION_BAR; +import static android.view.InsetsState.TYPE_SIDE_BAR_1; +import static android.view.InsetsState.TYPE_SIDE_BAR_2; +import static android.view.InsetsState.TYPE_SIDE_BAR_3; import static android.view.InsetsState.TYPE_TOP_BAR; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertNotEquals; import android.graphics.Rect; @@ -133,4 +138,13 @@ public class InsetsStateTest { p.recycle(); assertEquals(mState, mState2); } + + @Test + public void testGetDefaultVisibility() { + assertTrue(InsetsState.getDefaultVisibly(TYPE_TOP_BAR)); + assertTrue(InsetsState.getDefaultVisibly(TYPE_SIDE_BAR_1)); + assertTrue(InsetsState.getDefaultVisibly(TYPE_SIDE_BAR_2)); + assertTrue(InsetsState.getDefaultVisibly(TYPE_SIDE_BAR_3)); + assertFalse(InsetsState.getDefaultVisibly(TYPE_IME)); + } } diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml index f7541e0678d5..6a4079256268 100644 --- a/data/fonts/fonts.xml +++ b/data/fonts/fonts.xml @@ -319,9 +319,8 @@ <font weight="700" style="normal" fallbackFor="serif">NotoSerifMyanmar-Bold.otf</font> </family> <family lang="und-Mymr" variant="compact"> - <font weight="400" style="normal">NotoSansMyanmarUI-Regular.otf</font> - <font weight="500" style="normal">NotoSansMyanmarUI-Medium.otf</font> - <font weight="700" style="normal">NotoSansMyanmarUI-Bold.otf</font> + <font weight="400" style="normal">NotoSansMyanmarUI-Regular-ZawDecode.ttf</font> + <font weight="700" style="normal">NotoSansMyanmarUI-Bold-ZawDecode.ttf</font> </family> <family lang="und-Thaa"> <font weight="400" style="normal">NotoSansThaana-Regular.ttf</font> diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 6821282bd0a7..3342fd22caab 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -25,6 +25,7 @@ import android.annotation.Px; import android.annotation.Size; import android.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; +import android.os.Build; import android.os.LocaleList; import android.text.GraphicsOperations; import android.text.SpannableString; @@ -69,7 +70,7 @@ public class Paint { private MaskFilter mMaskFilter; private PathEffect mPathEffect; private Shader mShader; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private Typeface mTypeface; private Xfermode mXfermode; diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 10f6fae3cf6d..77e77c49973c 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -29,6 +29,7 @@ import android.graphics.Outline; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.graphics.Rect; +import android.os.Build; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.LayoutDirection; @@ -736,7 +737,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) protected DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, Resources res) { mOwner = owner; diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 9361c7c29bcb..213ed7d1ff0a 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; @@ -345,7 +346,7 @@ public class KeyStore { return list(prefix, UID_SELF); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean reset() { try { return mBinder.reset() == NO_ERROR; @@ -413,7 +414,7 @@ public class KeyStore { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean isEmpty() { return isEmpty(UserHandle.myUserId()); } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java index 953cef7d30ff..aa2917484a05 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -210,6 +210,10 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { throw new InvalidAlgorithmParameterException( "HMAC key size must be at least 64 bits."); } + if (mKeySizeBits > 512 && spec.isStrongBoxBacked()) { + throw new InvalidAlgorithmParameterException( + "StrongBox HMAC key size must be smaller than 512 bits."); + } // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm // implies SHA-256 digest). Because keymaster HMAC key is authorized only for diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index 5fc742afeaeb..d44c894fa573 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -303,7 +303,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato if (mKeySizeBits == -1) { mKeySizeBits = getDefaultKeySize(keymasterAlgorithm); } - checkValidKeySize(keymasterAlgorithm, mKeySizeBits); + checkValidKeySize(keymasterAlgorithm, mKeySizeBits, mSpec.isStrongBoxBacked()); if (spec.getKeystoreAlias() == null) { throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided"); @@ -724,10 +724,18 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } } - private static void checkValidKeySize(int keymasterAlgorithm, int keySize) + private static void checkValidKeySize( + int keymasterAlgorithm, + int keySize, + boolean isStrongBoxBacked) throws InvalidAlgorithmParameterException { switch (keymasterAlgorithm) { case KeymasterDefs.KM_ALGORITHM_EC: + if (isStrongBoxBacked && keySize != 256) { + throw new InvalidAlgorithmParameterException( + "Unsupported StrongBox EC key size: " + + keySize + " bits. Supported: 256"); + } if (!SUPPORTED_EC_NIST_CURVE_SIZES.contains(keySize)) { throw new InvalidAlgorithmParameterException("Unsupported EC key size: " + keySize + " bits. Supported: " + SUPPORTED_EC_NIST_CURVE_SIZES); diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in index bd1e6c5bf2e8..14e3a32817a0 100644 --- a/libs/hwui/DisplayListOps.in +++ b/libs/hwui/DisplayListOps.in @@ -41,14 +41,10 @@ X(DrawImage) X(DrawImageNine) X(DrawImageRect) X(DrawImageLattice) -X(DrawText) -X(DrawPosText) -X(DrawPosTextH) -X(DrawTextRSXform) X(DrawTextBlob) X(DrawPatch) X(DrawPoints) X(DrawVertices) X(DrawAtlas) X(DrawShadowRec) -X(DrawVectorDrawable)
\ No newline at end of file +X(DrawVectorDrawable) diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index fc813d20b1ac..6dc9d34cc3fd 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -373,61 +373,6 @@ struct DrawImageLattice final : Op { } }; -struct DrawText final : Op { - static const auto kType = Type::DrawText; - DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) - : bytes(bytes), x(x), y(y), paint(paint) {} - size_t bytes; - SkScalar x, y; - SkPaint paint; - void draw(SkCanvas* c, const SkMatrix&) const { - c->drawText(pod<void>(this), bytes, x, y, paint); - } -}; -struct DrawPosText final : Op { - static const auto kType = Type::DrawPosText; - DrawPosText(size_t bytes, const SkPaint& paint, int n) : bytes(bytes), paint(paint), n(n) {} - size_t bytes; - SkPaint paint; - int n; - void draw(SkCanvas* c, const SkMatrix&) const { - auto points = pod<SkPoint>(this); - auto text = pod<void>(this, n * sizeof(SkPoint)); - c->drawPosText(text, bytes, points, paint); - } -}; -struct DrawPosTextH final : Op { - static const auto kType = Type::DrawPosTextH; - DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint, int n) - : bytes(bytes), y(y), paint(paint), n(n) {} - size_t bytes; - SkScalar y; - SkPaint paint; - int n; - void draw(SkCanvas* c, const SkMatrix&) const { - auto xs = pod<SkScalar>(this); - auto text = pod<void>(this, n * sizeof(SkScalar)); - c->drawPosTextH(text, bytes, xs, y, paint); - } -}; -struct DrawTextRSXform final : Op { - static const auto kType = Type::DrawTextRSXform; - DrawTextRSXform(size_t bytes, int xforms, const SkRect* cull, const SkPaint& paint) - : bytes(bytes), xforms(xforms), paint(paint) { - if (cull) { - this->cull = *cull; - } - } - size_t bytes; - int xforms; - SkRect cull = kUnset; - SkPaint paint; - void draw(SkCanvas* c, const SkMatrix&) const { - // For alignment, the SkRSXforms are first in the pod section, followed by the text. - c->drawTextRSXform(pod<void>(this, xforms * sizeof(SkRSXform)), bytes, pod<SkRSXform>(this), - maybe_unset(cull), paint); - } -}; struct DrawTextBlob final : Op { static const auto kType = Type::DrawTextBlob; DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) @@ -682,33 +627,6 @@ void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanva fs); } -void DisplayListData::drawText(const void* text, size_t bytes, SkScalar x, SkScalar y, - const SkPaint& paint) { - void* pod = this->push<DrawText>(bytes, bytes, x, y, paint); - copy_v(pod, (const char*)text, bytes); - mHasText = true; -} -void DisplayListData::drawPosText(const void* text, size_t bytes, const SkPoint pos[], - const SkPaint& paint) { - int n = paint.countText(text, bytes); - void* pod = this->push<DrawPosText>(n * sizeof(SkPoint) + bytes, bytes, paint, n); - copy_v(pod, pos, n, (const char*)text, bytes); - mHasText = true; -} -void DisplayListData::drawPosTextH(const void* text, size_t bytes, const SkScalar xs[], SkScalar y, - const SkPaint& paint) { - int n = paint.countText(text, bytes); - void* pod = this->push<DrawPosTextH>(n * sizeof(SkScalar) + bytes, bytes, y, paint, n); - copy_v(pod, xs, n, (const char*)text, bytes); - mHasText = true; -} -void DisplayListData::drawTextRSXform(const void* text, size_t bytes, const SkRSXform xforms[], - const SkRect* cull, const SkPaint& paint) { - int n = paint.countText(text, bytes); - void* pod = this->push<DrawTextRSXform>(bytes + n * sizeof(SkRSXform), bytes, n, cull, paint); - copy_v(pod, xforms, n, (const char*)text, bytes); - mHasText = true; -} void DisplayListData::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) { this->push<DrawTextBlob>(0, blob, x, y, paint); @@ -932,10 +850,6 @@ void RecordingCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkD fDL->drawAnnotation(rect, key, val); } -void RecordingCanvas::onDrawTextRSXform(const void* text, size_t bytes, const SkRSXform xform[], - const SkRect* cull, const SkPaint& paint) { - fDL->drawTextRSXform(text, bytes, xform, cull, paint); -} void RecordingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) { fDL->drawTextBlob(blob, x, y, paint); diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index 22b3a63884ee..caaef67f724f 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -101,10 +101,6 @@ private: void drawDrawable(SkDrawable*, const SkMatrix*); void drawPicture(const SkPicture*, const SkMatrix*, const SkPaint*); - void drawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&); - void drawPosText(const void*, size_t, const SkPoint[], const SkPaint&); - void drawPosTextH(const void*, size_t, const SkScalar[], SkScalar, const SkPaint&); - void drawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*, const SkPaint&); void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&); void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*, BitmapPalette palette); @@ -173,8 +169,6 @@ public: void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; void onDrawAnnotation(const SkRect&, const char[], SkData*) override; - void onDrawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*, - const SkPaint&) override; void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint*) override; diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 83b9e7f6a3b8..ab95e69c4e26 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -710,6 +710,7 @@ void SkiaCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& p void SkiaCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset, const SkPaint& paint, const SkPath& path, size_t start, size_t end) { + SkFont font = SkFont::LEGACY_ExtractFromPaint(paint); SkPaint paintCopy(paint); if (mPaintFilter) { mPaintFilter->filter(&paintCopy); @@ -717,9 +718,10 @@ void SkiaCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, SkASSERT(paintCopy.getTextEncoding() == kGlyphID_SkTextEncoding); const int N = end - start; - SkAutoSTMalloc<1024, uint8_t> storage(N * (sizeof(uint16_t) + sizeof(SkRSXform))); - SkRSXform* xform = (SkRSXform*)storage.get(); - uint16_t* glyphs = (uint16_t*)(xform + N); + SkTextBlobBuilder builder; + auto rec = builder.allocRunRSXform(font, N); + SkRSXform* xform = (SkRSXform*)rec.pos; + uint16_t* glyphs = rec.glyphs; SkPathMeasure meas(path, false); for (size_t i = start; i < end; i++) { @@ -740,7 +742,7 @@ void SkiaCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, xform[i - start].fTy = pos.y() + tan.x() * y - halfWidth * tan.y(); } - this->asSkCanvas()->drawTextRSXform(glyphs, sizeof(uint16_t) * N, xform, nullptr, paintCopy); + this->asSkCanvas()->drawTextBlob(builder.make(), 0, 0, paintCopy); } // ---------------------------------------------------------------------------- diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h index 2b5d58051c2c..0eb526af127a 100644 --- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h +++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h @@ -82,11 +82,6 @@ protected: mOutput << mIdent << "drawDRRect" << std::endl; } - void onDrawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*, - const SkPaint&) override { - mOutput << mIdent << "drawTextRSXform" << std::endl; - } - void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override { mOutput << mIdent << "drawTextBlob" << std::endl; } diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index f2906de4d5a0..ff873133c6fb 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -30,7 +30,7 @@ namespace skiapipeline { class SkiaPipeline : public renderthread::IRenderPipeline { public: - SkiaPipeline(renderthread::RenderThread& thread); + explicit SkiaPipeline(renderthread::RenderThread& thread); virtual ~SkiaPipeline(); TaskManager* getTaskManager() override; diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h index daa4c1839693..dc8420f4e01b 100644 --- a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h +++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h @@ -23,7 +23,7 @@ namespace uirenderer { class SkiaProfileRenderer : public IProfileRenderer { public: - SkiaProfileRenderer(SkCanvas* canvas) : mCanvas(canvas) {} + explicit SkiaProfileRenderer(SkCanvas* canvas) : mCanvas(canvas) {} void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override; void drawRects(const float* rects, int count, const SkPaint& paint) override; diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h index 02874c7d2c69..53ffc4422fd7 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -25,7 +25,7 @@ namespace skiapipeline { class SkiaVulkanPipeline : public SkiaPipeline { public: - SkiaVulkanPipeline(renderthread::RenderThread& thread); + explicit SkiaVulkanPipeline(renderthread::RenderThread& thread); virtual ~SkiaVulkanPipeline() {} renderthread::MakeCurrentResult makeCurrent() override; diff --git a/libs/hwui/pipeline/skia/VectorDrawableAtlas.h b/libs/hwui/pipeline/skia/VectorDrawableAtlas.h index 74e48cea2a87..5e892aa7e92c 100644 --- a/libs/hwui/pipeline/skia/VectorDrawableAtlas.h +++ b/libs/hwui/pipeline/skia/VectorDrawableAtlas.h @@ -62,8 +62,8 @@ class VectorDrawableAtlas : public virtual RefBase { public: enum class StorageMode { allowSharedSurface, disallowSharedSurface }; - VectorDrawableAtlas(size_t surfaceArea, - StorageMode storageMode = StorageMode::allowSharedSurface); + explicit VectorDrawableAtlas(size_t surfaceArea, + StorageMode storageMode = StorageMode::allowSharedSurface); /** * "prepareForDraw" may allocate a new surface if needed. It may schedule to repack the diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp index 9a1ee54bff49..4111bd24847e 100644 --- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp +++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp @@ -16,7 +16,7 @@ #include "TestSceneBase.h" #include "tests/common/TestListViewSceneBase.h" - +#include <SkFont.h> #include <cstdio> class ListViewAnimation; @@ -46,11 +46,13 @@ class ListViewAnimation : public TestListViewSceneBase { SkColorGetR(randomColor) + SkColorGetG(randomColor) + SkColorGetB(randomColor) < 128 * 3; paint.setColor(bgDark ? Color::White : Color::Grey_700); - paint.setTextSize(size / 2); + + SkFont font; + font.setSize(size / 2); char charToShow = 'A' + (rand() % 26); - const SkPoint pos[] = {{SkIntToScalar(size / 2), - /*approximate centering*/ SkFloatToScalar(size * 0.7f)}}; - canvas.drawPosText(&charToShow, 1, pos, paint); + const SkPoint pos = {SkIntToScalar(size / 2), + /*approximate centering*/ SkFloatToScalar(size * 0.7f)}; + canvas.drawSimpleText(&charToShow, 1, kUTF8_SkTextEncoding, pos.fX, pos.fY, font, paint); return bitmap; } diff --git a/libs/hwui/tests/unit/FatalTestCanvas.h b/libs/hwui/tests/unit/FatalTestCanvas.h index 146662b1e913..1723c2eb4948 100644 --- a/libs/hwui/tests/unit/FatalTestCanvas.h +++ b/libs/hwui/tests/unit/FatalTestCanvas.h @@ -30,10 +30,6 @@ public: void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) { ADD_FAILURE() << "onDrawDRRect not expected in this test"; } - void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform[], - const SkRect* cullRect, const SkPaint& paint) { - ADD_FAILURE() << "onDrawTextRSXform not expected in this test"; - } void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) { ADD_FAILURE() << "onDrawTextBlob not expected in this test"; } @@ -116,4 +112,4 @@ public: int mDrawCounter = 0; // counts how may draw calls of any kind were made to this canvas }; -}
\ No newline at end of file +} diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include/android/os/IncidentReportArgs.h index c56f689b7419..ee1e33c43b89 100644 --- a/libs/incident/include/android/os/IncidentReportArgs.h +++ b/libs/incident/include/android/os/IncidentReportArgs.h @@ -40,7 +40,7 @@ const uint8_t DEST_AUTOMATIC = 200; class IncidentReportArgs : public Parcelable { public: IncidentReportArgs(); - explicit IncidentReportArgs(const IncidentReportArgs& that); + IncidentReportArgs(const IncidentReportArgs& that); virtual ~IncidentReportArgs(); virtual status_t writeToParcel(Parcel* out) const; diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java index d90a597b1cbb..609a15e1be7e 100644 --- a/location/java/android/location/GpsStatus.java +++ b/location/java/android/location/GpsStatus.java @@ -17,6 +17,7 @@ package android.location; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.SparseArray; import java.util.Iterator; @@ -207,7 +208,7 @@ public final class GpsStatus { status.mAzimuths); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) void setTimeToFirstFix(int ttff) { mTimeToFirstFix = ttff; } diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 70a97e1f7da0..fbebbb11ffd5 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -19,6 +19,7 @@ package android.location; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -124,7 +125,7 @@ public class Location implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mProvider; private long mTime = 0; @UnsupportedAppUsage diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 040e4f9f1bd0..d96597bb3b69 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -2372,7 +2372,7 @@ public class LocationManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean sendNiResponse(int notifId, int userResponse) { try { return mService.sendNiResponse(notifId, userResponse); diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index 2d7f7e309004..154bd563fb0f 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -18,6 +18,7 @@ package android.location; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -142,19 +143,19 @@ public final class LocationRequest implements Parcelable { */ private static final double FASTEST_INTERVAL_FACTOR = 6.0; // 6x - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mQuality = POWER_LOW; @UnsupportedAppUsage private long mInterval = 60 * 60 * 1000; // 60 minutes - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private long mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR); // 10 minutes - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mExplicitFastestInterval = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private long mExpireAt = Long.MAX_VALUE; // no expiry - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mNumUpdates = Integer.MAX_VALUE; // no expiry - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private float mSmallestDisplacement = 0.0f; // meters @UnsupportedAppUsage private WorkSource mWorkSource = null; @@ -603,14 +604,14 @@ public final class LocationRequest implements Parcelable { return mHideFromAppOps; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static void checkInterval(long millis) { if (millis < 0) { throw new IllegalArgumentException("invalid interval: " + millis); } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static void checkQuality(int quality) { switch (quality) { case ACCURACY_FINE: @@ -625,14 +626,14 @@ public final class LocationRequest implements Parcelable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static void checkDisplacement(float meters) { if (meters < 0.0f) { throw new IllegalArgumentException("invalid displacement: " + meters); } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static void checkProvider(String name) { if (name == null) { throw new IllegalArgumentException("invalid provider: " + name); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index da52a268e384..30b5480fba55 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -67,6 +67,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; @@ -539,37 +540,42 @@ public class AudioManager { /** * Adjusting the volume due to a hardware key press. + * This flag can be used in the places in order to denote (or check) that a volume adjustment + * request is from a hardware key press. (e.g. {@link MediaController}). * @hide */ @SystemApi - public static final int FLAG_FROM_KEY = 1 << 12; - - private static final String[] FLAG_NAMES = { - "FLAG_SHOW_UI", - "FLAG_ALLOW_RINGER_MODES", - "FLAG_PLAY_SOUND", - "FLAG_REMOVE_SOUND_AND_VIBRATE", - "FLAG_VIBRATE", - "FLAG_FIXED_VOLUME", - "FLAG_BLUETOOTH_ABS_VOLUME", - "FLAG_SHOW_SILENT_HINT", - "FLAG_HDMI_SYSTEM_AUDIO_VOLUME", - "FLAG_ACTIVE_MEDIA_ONLY", - "FLAG_SHOW_UI_WARNINGS", - "FLAG_SHOW_VIBRATE_HINT", - "FLAG_FROM_KEY", - }; + public static final int FLAG_FROM_KEY = 1 << 16; + + // The iterator of TreeMap#entrySet() returns the entries in ascending key order. + private static final TreeMap<Integer, String> FLAG_NAMES = new TreeMap<>(); + + static { + FLAG_NAMES.put(FLAG_SHOW_UI, "FLAG_SHOW_UI"); + FLAG_NAMES.put(FLAG_ALLOW_RINGER_MODES, "FLAG_ALLOW_RINGER_MODES"); + FLAG_NAMES.put(FLAG_PLAY_SOUND, "FLAG_PLAY_SOUND"); + FLAG_NAMES.put(FLAG_REMOVE_SOUND_AND_VIBRATE, "FLAG_REMOVE_SOUND_AND_VIBRATE"); + FLAG_NAMES.put(FLAG_VIBRATE, "FLAG_VIBRATE"); + FLAG_NAMES.put(FLAG_FIXED_VOLUME, "FLAG_FIXED_VOLUME"); + FLAG_NAMES.put(FLAG_BLUETOOTH_ABS_VOLUME, "FLAG_BLUETOOTH_ABS_VOLUME"); + FLAG_NAMES.put(FLAG_SHOW_SILENT_HINT, "FLAG_SHOW_SILENT_HINT"); + FLAG_NAMES.put(FLAG_HDMI_SYSTEM_AUDIO_VOLUME, "FLAG_HDMI_SYSTEM_AUDIO_VOLUME"); + FLAG_NAMES.put(FLAG_ACTIVE_MEDIA_ONLY, "FLAG_ACTIVE_MEDIA_ONLY"); + FLAG_NAMES.put(FLAG_SHOW_UI_WARNINGS, "FLAG_SHOW_UI_WARNINGS"); + FLAG_NAMES.put(FLAG_SHOW_VIBRATE_HINT, "FLAG_SHOW_VIBRATE_HINT"); + FLAG_NAMES.put(FLAG_FROM_KEY, "FLAG_FROM_KEY"); + } /** @hide */ public static String flagsToString(int flags) { final StringBuilder sb = new StringBuilder(); - for (int i = 0; i < FLAG_NAMES.length; i++) { - final int flag = 1 << i; + for (Map.Entry<Integer, String> entry : FLAG_NAMES.entrySet()) { + final int flag = entry.getKey(); if ((flags & flag) != 0) { if (sb.length() > 0) { sb.append(','); } - sb.append(FLAG_NAMES[i]); + sb.append(entry.getValue()); flags &= ~flag; } } @@ -4274,9 +4280,8 @@ public class AudioManager { * Return codes for listAudioPorts(), createAudioPatch() ... */ - /** @hide - * CANDIDATE FOR PUBLIC API - */ + /** @hide */ + @SystemApi public static final int SUCCESS = AudioSystem.SUCCESS; /** * A default error code. diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 58fc1ab1c4dd..45cde0ffecc4 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -916,6 +916,13 @@ public class AudioSystem public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register); + /** see AudioPolicy.setUidDeviceAffinities() */ + public static native int setUidDeviceAffinities(int uid, @NonNull int[] types, + @NonNull String[] addresses); + + /** see AudioPolicy.removeUidDeviceAffinities() */ + public static native int removeUidDeviceAffinities(int uid); + public static native int systemReady(); public static native float getStreamVolumeDB(int stream, int index, int device); diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index aa123bdc9cff..4f74ec911499 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -19,6 +19,7 @@ package android.media; import android.annotation.UnsupportedAppUsage; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; +import android.os.Build; /** * Retrieves the @@ -496,7 +497,7 @@ public class CamcorderProfile } // Methods implemented by JNI - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static native final void native_init(); @UnsupportedAppUsage private static native final CamcorderProfile native_get_camcorder_profile( diff --git a/media/java/android/media/Controller2Link.aidl b/media/java/android/media/Controller2Link.aidl new file mode 100644 index 000000000000..64edafcb11fc --- /dev/null +++ b/media/java/android/media/Controller2Link.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +parcelable Controller2Link; diff --git a/media/java/android/media/Controller2Link.java b/media/java/android/media/Controller2Link.java new file mode 100644 index 000000000000..a62db5f1fb20 --- /dev/null +++ b/media/java/android/media/Controller2Link.java @@ -0,0 +1,171 @@ +/* + * 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.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.RemoteException; +import android.os.ResultReceiver; + +import java.util.Objects; + +/** + * Handles incoming commands from {@link MediaSession2} to both {@link MediaController2}. + * @hide + */ +// @SystemApi +public final class Controller2Link implements Parcelable { + private static final String TAG = "Controller2Link"; + private static final boolean DEBUG = MediaController2.DEBUG; + + public static final Parcelable.Creator<Controller2Link> CREATOR = + new Parcelable.Creator<Controller2Link>() { + @Override + public Controller2Link createFromParcel(Parcel in) { + return new Controller2Link(in); + } + + @Override + public Controller2Link[] newArray(int size) { + return new Controller2Link[size]; + } + }; + + + private final MediaController2 mController; + private final IMediaController2 mIController; + + public Controller2Link(MediaController2 controller) { + mController = controller; + mIController = new Controller2Stub(); + } + + Controller2Link(Parcel in) { + mController = null; + mIController = IMediaController2.Stub.asInterface(in.readStrongBinder()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeStrongBinder(mIController.asBinder()); + } + + @Override + public int hashCode() { + return mIController.asBinder().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Controller2Link)) { + return false; + } + Controller2Link other = (Controller2Link) obj; + return Objects.equals(mIController.asBinder(), other.mIController.asBinder()); + } + + /** Interface method for IMediaController2.notifyConnected */ + public void notifyConnected(int seq, Bundle connectionResult) { + try { + mIController.notifyConnected(seq, connectionResult); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaController2.notifyDisonnected */ + public void notifyDisconnected(int seq) { + try { + mIController.notifyDisconnected(seq); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaController2.sendSessionCommand */ + public void sendSessionCommand(int seq, Session2Command command, Bundle args, + ResultReceiver resultReceiver) { + try { + mIController.sendSessionCommand(seq, command, args, resultReceiver); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaController2.cancelSessionCommand */ + public void cancelSessionCommand(int seq) { + try { + mIController.cancelSessionCommand(seq); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Stub implementation for IMediaController2.notifyConnected */ + public void onConnected(int seq, Bundle connectionResult) { + if (connectionResult == null) { + onDisconnected(seq); + return; + } + mController.onConnected(seq, connectionResult); + } + + /** Stub implementation for IMediaController2.notifyDisonnected */ + public void onDisconnected(int seq) { + mController.onDisconnected(seq); + } + + /** Stub implementation for IMediaController2.sendSessionCommand */ + public void onSessionCommand(int seq, Session2Command command, Bundle args, + ResultReceiver resultReceiver) { + mController.onSessionCommand(seq, command, args, resultReceiver); + } + + /** Stub implementation for IMediaController2.cancelSessionCommand */ + public void onCancelCommand(int seq) { + mController.onCancelCommand(seq); + } + + private class Controller2Stub extends IMediaController2.Stub { + @Override + public void notifyConnected(int seq, Bundle connectionResult) { + Controller2Link.this.onConnected(seq, connectionResult); + } + + @Override + public void notifyDisconnected(int seq) { + Controller2Link.this.onDisconnected(seq); + } + + @Override + public void sendSessionCommand(int seq, Session2Command command, Bundle args, + ResultReceiver resultReceiver) { + Controller2Link.this.onSessionCommand(seq, command, args, resultReceiver); + } + + @Override + public void cancelSessionCommand(int seq) { + Controller2Link.this.onCancelCommand(seq); + } + } +} diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 32c4643adad0..b9088d417dad 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -24,6 +24,7 @@ import android.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.os.Build; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -469,7 +470,7 @@ public class ExifInterface { // See http://www.exiv2.org/makernote.html#R11 private static final int PEF_MAKER_NOTE_SKIP_SIZE = 6; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static SimpleDateFormat sFormatter; // See Exchangeable image file format for digital still cameras: Exif version 2.2. @@ -1303,7 +1304,7 @@ public class ExifInterface { sExifPointerTagMap.put(EXIF_POINTER_TAGS[5].number, IFD_TYPE_ORF_IMAGE_PROCESSING); // 8256 } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final String mFilename; private final FileDescriptor mSeekableFileDescriptor; private final AssetManager.AssetInputStream mAssetInputStream; @@ -1313,7 +1314,7 @@ public class ExifInterface { private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length]; private Set<Integer> mAttributesOffsets = new HashSet<>(EXIF_TAGS.length); private ByteOrder mExifByteOrder = ByteOrder.BIG_ENDIAN; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mHasThumbnail; // The following values used for indicating a thumbnail position. private int mThumbnailOffset; @@ -2177,7 +2178,7 @@ public class ExifInterface { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static float convertRationalLatLonToFloat(String rationalString, String ref) { try { String [] parts = rationalString.split(","); diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index abd64119de61..9fbd7eac6e8a 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -223,6 +223,11 @@ interface IAudioService { boolean isAudioServerRunning(); + int setUidDeviceAffinity(in IAudioPolicyCallback pcb, in int uid, in int[] deviceTypes, + in String[] deviceAddresses); + + int removeUidDeviceAffinity(in IAudioPolicyCallback pcb, in int uid); + // 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/IMediaController2.aidl b/media/java/android/media/IMediaController2.aidl new file mode 100644 index 000000000000..ca5394f504cb --- /dev/null +++ b/media/java/android/media/IMediaController2.aidl @@ -0,0 +1,38 @@ +/* + * 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.os.Bundle; +import android.os.ResultReceiver; +import android.media.Session2Command; + +/** + * Interface from MediaSession2 to MediaController2. + * <p> + * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, + * and holds calls from session to make session owner(s) frozen. + * @hide + */ + // Code for AML only +oneway interface IMediaController2 { + void notifyConnected(int seq, in Bundle connectionResult) = 0; + void notifyDisconnected(int seq) = 1; + void sendSessionCommand(int seq, in Session2Command command, in Bundle args, + in ResultReceiver resultReceiver) = 2; + void cancelSessionCommand(int seq) = 3; + // Next Id : 4 +} diff --git a/media/java/android/media/IMediaSession2.aidl b/media/java/android/media/IMediaSession2.aidl new file mode 100644 index 000000000000..26e717b39afc --- /dev/null +++ b/media/java/android/media/IMediaSession2.aidl @@ -0,0 +1,39 @@ +/* + * 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.os.Bundle; +import android.os.ResultReceiver; +import android.media.Controller2Link; +import android.media.Session2Command; + +/** + * Interface from MediaController2 to MediaSession2. + * <p> + * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, + * and holds calls from session to make session owner(s) frozen. + * @hide + */ + // Code for AML only +oneway interface IMediaSession2 { + void connect(in Controller2Link caller, int seq, in Bundle connectionRequest) = 0; + void disconnect(in Controller2Link caller, int seq) = 1; + void sendSessionCommand(in Controller2Link caller, int seq, in Session2Command sessionCommand, + in Bundle args, in ResultReceiver resultReceiver) = 2; + void cancelSessionCommand(in Controller2Link caller, int seq) = 3; + // Next Id : 4 +} diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 902582905b0e..10a1e3a72225 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -972,7 +972,7 @@ public final class MediaCodecInfo { * {@code null}. The array is sorted in ascending order. */ public int[] getSupportedSampleRates() { - return Arrays.copyOf(mSampleRates, mSampleRates.length); + return mSampleRates != null ? Arrays.copyOf(mSampleRates, mSampleRates.length) : null; } /** diff --git a/media/java/android/media/MediaConstants.java b/media/java/android/media/MediaConstants.java new file mode 100644 index 000000000000..275b0acd8ad6 --- /dev/null +++ b/media/java/android/media/MediaConstants.java @@ -0,0 +1,32 @@ +/* + * 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; + +class MediaConstants { + // Bundle key for int + static final String KEY_PID = "android.media.key.PID"; + + // Bundle key for String + static final String KEY_PACKAGE_NAME = "android.media.key.PACKAGE_NAME"; + + // Bundle key for Parcelable + static final String KEY_SESSION2_STUB = "android.media.key.SESSION2_STUB"; + static final String KEY_ALLOWED_COMMANDS = "android.media.key.ALLOWED_COMMANDS"; + + private MediaConstants() { + } +} diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java new file mode 100644 index 000000000000..7665c92f9264 --- /dev/null +++ b/media/java/android/media/MediaController2.java @@ -0,0 +1,369 @@ +/* + * 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 static android.media.MediaConstants.KEY_ALLOWED_COMMANDS; +import static android.media.MediaConstants.KEY_PACKAGE_NAME; +import static android.media.MediaConstants.KEY_PID; +import static android.media.MediaConstants.KEY_SESSION2_STUB; +import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Token.TYPE_SESSION; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.os.Binder; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Process; +import android.os.ResultReceiver; +import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.Log; + +import java.util.concurrent.Executor; + +/** + * Allows an app to interact with an active {@link MediaSession2} or a + * {@link MediaSession2Service} which would provide {@link MediaSession2}. Media buttons and other + * commands can be sent to the session. + * <p> + * This API is not generally intended for third party application developers. + * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> + * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> + * for consistent behavior across all devices. + * @hide + */ +public class MediaController2 implements AutoCloseable { + static final String TAG = "MediaController2"; + static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final ControllerCallback mCallback; + + private final IBinder.DeathRecipient mDeathRecipient = () -> close(); + private final Context mContext; + private final Session2Token mSessionToken; + private final Executor mCallbackExecutor; + private final Controller2Link mControllerStub; + private final Handler mResultHandler; + + private final Object mLock = new Object(); + //@GuardedBy("mLock") + private int mNextSeqNumber; + //@GuardedBy("mLock") + private Session2Link mSessionBinder; + //@GuardedBy("mLock") + private Session2CommandGroup mAllowedCommands; + //@GuardedBy("mLock") + private Session2Token mConnectedToken; + //@GuardedBy("mLock") + private ArrayMap<ResultReceiver, Integer> mPendingCommands; + //@GuardedBy("mLock") + private ArraySet<Integer> mRequestedCommandSeqNumbers; + + /** + * Create a {@link MediaController2} from the {@link Session2Token}. + * This connects to the session and may wake up the service if it's not available. + * + * @param context Context + * @param token token to connect to + */ + public MediaController2(@NonNull Context context, @NonNull Session2Token token) { + this(context, token, context.getMainExecutor(), new ControllerCallback() {}); + } + + /** + * Create a {@link MediaController2} from the {@link Session2Token}. + * This connects to the session and may wake up the service if it's not available. + * + * @param context Context + * @param token token to connect to + * @param executor executor to run callbacks on. + * @param callback controller callback to receive changes in. + */ + public MediaController2(@NonNull Context context, @NonNull Session2Token token, + @NonNull Executor executor, @NonNull ControllerCallback callback) { + if (context == null) { + throw new IllegalArgumentException("context shouldn't be null"); + } + if (token == null) { + throw new IllegalArgumentException("token shouldn't be null"); + } + mContext = context; + mSessionToken = token; + mCallbackExecutor = (executor == null) ? context.getMainExecutor() : executor; + mCallback = (callback == null) ? new ControllerCallback() { } : callback; + mControllerStub = new Controller2Link(this); + // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked. + mResultHandler = new Handler(context.getMainLooper()); + + mNextSeqNumber = 0; + mPendingCommands = new ArrayMap<>(); + mRequestedCommandSeqNumbers = new ArraySet<>(); + + if (token.getType() == TYPE_SESSION) { + connectToSession(); + } else { + // TODO: Handle connect to session service. + } + } + + @Override + public void close() { + synchronized (mLock) { + if (mSessionBinder != null) { + try { + mSessionBinder.unlinkToDeath(mDeathRecipient, 0); + mSessionBinder.disconnect(mControllerStub, getNextSeqNumber()); + } catch (RuntimeException e) { + // No-op + } + } + mPendingCommands.clear(); + mRequestedCommandSeqNumbers.clear(); + mCallbackExecutor.execute(() -> { + mCallback.onDisconnected(MediaController2.this); + }); + mSessionBinder = null; + } + } + + /** + * Sends a session command to the session + * <p> + * @param command the session command + * @param args optional arguments + * @return a token which will be sent together in {@link ControllerCallback#onCommandResult} + * when its result is received. + */ + public Object sendSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) { + if (command == null) { + throw new IllegalArgumentException("command shouldn't be null"); + } + + ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) { + protected void onReceiveResult(int resultCode, Bundle resultData) { + synchronized (mLock) { + mPendingCommands.remove(this); + } + mCallbackExecutor.execute(() -> { + mCallback.onCommandResult(MediaController2.this, this, + command, new Session2Command.Result(resultCode, resultData)); + }); + } + }; + + synchronized (mLock) { + if (mSessionBinder != null) { + int seq = getNextSeqNumber(); + mPendingCommands.put(resultReceiver, seq); + try { + mSessionBinder.sendSessionCommand(mControllerStub, seq, command, args, + resultReceiver); + } catch (RuntimeException e) { + mPendingCommands.remove(resultReceiver); + resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null); + } + } + } + return resultReceiver; + } + + /** + * Cancels the session command previously sent. + * + * @param token the token which is returned from {@link #sendSessionCommand}. + */ + public void cancelSessionCommand(@NonNull Object token) { + if (token == null) { + throw new IllegalArgumentException("token shouldn't be null"); + } + synchronized (mLock) { + if (mSessionBinder == null) return; + Integer seq = mPendingCommands.remove(token); + if (seq != null) { + mSessionBinder.cancelSessionCommand(mControllerStub, seq); + } + } + } + + // Called by Controller2Link.onConnected + void onConnected(int seq, Bundle connectionResult) { + final long token = Binder.clearCallingIdentity(); + try { + Session2Link sessionBinder = connectionResult.getParcelable(KEY_SESSION2_STUB); + Session2CommandGroup allowedCommands = + connectionResult.getParcelable(KEY_ALLOWED_COMMANDS); + if (DEBUG) { + Log.d(TAG, "notifyConnected sessionBinder=" + sessionBinder + + ", allowedCommands=" + allowedCommands); + } + if (sessionBinder == null || allowedCommands == null) { + // Connection rejected. + close(); + return; + } + synchronized (mLock) { + mSessionBinder = sessionBinder; + mAllowedCommands = allowedCommands; + // Implementation for the local binder is no-op, + // so can be used without worrying about deadlock. + sessionBinder.linkToDeath(mDeathRecipient, 0); + mConnectedToken = new Session2Token(mSessionToken.getUid(), TYPE_SESSION, + mSessionToken.getPackageName(), sessionBinder); + } + mCallbackExecutor.execute(() -> { + mCallback.onConnected(MediaController2.this, allowedCommands); + }); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Called by Controller2Link.onDisconnected + void onDisconnected(int seq) { + final long token = Binder.clearCallingIdentity(); + try { + // close() will call mCallback.onDisconnected + close(); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Called by Controller2Link.onSessionCommand + void onSessionCommand(int seq, Session2Command command, Bundle args, + @Nullable ResultReceiver resultReceiver) { + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + mRequestedCommandSeqNumbers.add(seq); + } + mCallbackExecutor.execute(() -> { + boolean isCanceled; + synchronized (mLock) { + isCanceled = !mRequestedCommandSeqNumbers.remove(seq); + } + if (isCanceled) { + resultReceiver.send(RESULT_INFO_SKIPPED, null); + return; + } + Session2Command.Result result = mCallback.onSessionCommand( + MediaController2.this, command, args); + if (resultReceiver != null) { + if (result == null) { + throw new RuntimeException("onSessionCommand shouldn't return null"); + } else { + resultReceiver.send(result.getResultCode(), result.getResultData()); + } + } + }); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Called by Controller2Link.onSessionCommand + void onCancelCommand(int seq) { + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + mRequestedCommandSeqNumbers.remove(seq); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private int getNextSeqNumber() { + synchronized (mLock) { + return mNextSeqNumber++; + } + } + + private void connectToSession() { + Session2Link sessionBinder = mSessionToken.getSessionLink(); + Bundle connectionRequest = new Bundle(); + connectionRequest.putString(KEY_PACKAGE_NAME, mContext.getPackageName()); + connectionRequest.putInt(KEY_PID, Process.myPid()); + + try { + sessionBinder.connect(mControllerStub, getNextSeqNumber(), connectionRequest); + } catch (RuntimeException e) { + Log.w(TAG, "Failed to call connection request. Framework will retry" + + " automatically"); + } + } + + /** + * Interface for listening to change in activeness of the {@link MediaSession2}. + * <p> + * This API is not generally intended for third party application developers. + */ + public abstract static class ControllerCallback { + /** + * Called when the controller is successfully connected to the session. The controller + * becomes available afterwards. + * + * @param controller the controller for this event + * @param allowedCommands commands that's allowed by the session. + */ + public void onConnected(@NonNull MediaController2 controller, + @NonNull Session2CommandGroup allowedCommands) { } + + /** + * Called when the session refuses the controller or the controller is disconnected from + * the session. The controller becomes unavailable afterwards and the callback wouldn't + * be called. + * <p> + * It will be also called after the {@link #close()}, so you can put clean up code here. + * You don't need to call {@link #close()} after this. + * + * @param controller the controller for this event + */ + public void onDisconnected(@NonNull MediaController2 controller) { } + + /** + * Called when the connected session sent a session command. + * + * @param controller the controller for this event + * @param command the session command + * @param args optional arguments + * @return the result for the session command. A runtime exception will be thrown if null + * is returned. + */ + @NonNull + public Session2Command.Result onSessionCommand(@NonNull MediaController2 controller, + @NonNull Session2Command command, @Nullable Bundle args) { + return null; + } + + /** + * Called when the command sent to the connected session is finished. + * + * @param controller the controller for this event + * @param token the token got from {@link MediaController2#sendSessionCommand} + * @param command the session command + * @param result the result of the session command + */ + public void onCommandResult(@NonNull MediaController2 controller, @NonNull Object token, + @NonNull Session2Command command, @NonNull Session2Command.Result result) { } + } +} diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java index aa2a937956c5..235325ebaf06 100644 --- a/media/java/android/media/MediaItem2.java +++ b/media/java/android/media/MediaItem2.java @@ -33,25 +33,13 @@ import java.util.List; import java.util.concurrent.Executor; /** - * A class with information on a single media item with the metadata information. Here are use - * cases. - * <ul> - * <li>Specify media items to {@link SessionPlayer2} for playback. - * <li>Share media items across the processes. - * </ul> - * <p> - * Subclasses of the session player may only accept certain subclasses of the media items. Check - * the player documentation that you're interested in. - * <p> - * When it's shared across the processes, we cannot guarantee that they contain the right values - * because media items are application dependent especially for the metadata. - * <p> - * This object is thread safe. + * A class with information on a single media item with the metadata information. * <p> * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> - * {@link androidx.media2.MediaItem} for consistent behavior across all devices. - * </p> + * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> + * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> + * for consistent behavior across all devices. + * <p> * @hide */ public class MediaItem2 implements Parcelable { diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index d656fa359826..33b8c4202fdd 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Build; import android.os.IBinder; import java.io.FileDescriptor; @@ -681,12 +682,12 @@ public class MediaMetadataRetriever implements AutoCloseable { * allocated internally. */ public native void release(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private native void native_setup(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static native void native_init(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private native final void native_finalize(); @Override diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java index 34345b31ded1..cef66147f395 100644 --- a/media/java/android/media/MediaPlayer2.java +++ b/media/java/android/media/MediaPlayer2.java @@ -436,13 +436,6 @@ public class MediaPlayer2 implements AutoCloseable */ // This is a synchronous call. public void reset() { - synchronized (mEventCbLock) { - mEventCallbackRecords.clear(); - } - synchronized (mDrmEventCbLock) { - mDrmEventCallbackRecords.clear(); - } - clearSourceInfos(); stayAwake(false); @@ -2758,6 +2751,12 @@ public class MediaPlayer2 implements AutoCloseable "Illegal null Executor for the EventCallback"); } synchronized (mEventCbLock) { + for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) { + if (cb.first == executor && cb.second == eventCallback) { + Log.w(TAG, "The callback has been registered before."); + return; + } + } mEventCallbackRecords.add(new Pair(executor, eventCallback)); } } diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 1cdc29102758..b16002900799 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -24,6 +24,7 @@ import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.hardware.Camera; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -105,12 +106,12 @@ public class MediaRecorder implements AudioRouting, @UnsupportedAppUsage private Surface mSurface; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mPath; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private FileDescriptor mFd; private File mFile; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private EventHandler mEventHandler; @UnsupportedAppUsage private OnErrorListener mOnErrorListener; @@ -479,7 +480,7 @@ public class MediaRecorder implements AudioRouting, public static final int HE_AAC = 4; /** Enhanced Low Delay AAC (AAC-ELD) audio codec */ public static final int AAC_ELD = 5; - /** Ogg Vorbis audio codec */ + /** Ogg Vorbis audio codec (Support is optional) */ public static final int VORBIS = 6; /** Opus audio codec */ public static final int OPUS = 7; @@ -958,7 +959,7 @@ public class MediaRecorder implements AudioRouting, // native implementation private native void _setOutputFile(FileDescriptor fd) throws IllegalStateException, IOException; private native void _setNextOutputFile(FileDescriptor fd) throws IllegalStateException, IOException; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private native void _prepare() throws IllegalStateException, IOException; /** @@ -1060,7 +1061,7 @@ public class MediaRecorder implements AudioRouting, mEventHandler.removeCallbacksAndMessages(null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private native void native_reset(); /** @@ -1569,14 +1570,14 @@ public class MediaRecorder implements AudioRouting, */ public native void release(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static native final void native_init(); @UnsupportedAppUsage private native final void native_setup(Object mediarecorder_this, String clientName, String opPackageName) throws IllegalStateException; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private native final void native_finalize(); @UnsupportedAppUsage diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java new file mode 100644 index 000000000000..b874ba461c2b --- /dev/null +++ b/media/java/android/media/MediaSession2.java @@ -0,0 +1,704 @@ +/* + * 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 static android.media.MediaConstants.KEY_ALLOWED_COMMANDS; +import static android.media.MediaConstants.KEY_PACKAGE_NAME; +import static android.media.MediaConstants.KEY_PID; +import static android.media.MediaConstants.KEY_SESSION2_STUB; +import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Token.TYPE_SESSION; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.media.session.MediaSessionManager; +import android.media.session.MediaSessionManager.RemoteUserInfo; +import android.os.Binder; +import android.os.Bundle; +import android.os.Handler; +import android.os.Process; +import android.os.ResultReceiver; +import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Executor; + +/** + * Allows a media app to expose its transport controls and playback information in a process to + * other processes including the Android framework and other apps. + * <p> + * This API is not generally intended for third party application developers. + * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> + * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> + * for consistent behavior across all devices. + * @hide + */ +public class MediaSession2 implements AutoCloseable { + static final String TAG = "MediaSession"; + static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + // Note: This checks the uniqueness of a session ID only in a single process. + // When the framework becomes able to check the uniqueness, this logic should be removed. + //@GuardedBy("MediaSession.class") + private static final List<String> SESSION_ID_LIST = new ArrayList<>(); + + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final Object mLock = new Object(); + //@GuardedBy("mLock") + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final Map<Controller2Link, ControllerInfo> mConnectedControllers = new HashMap<>(); + + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final Context mContext; + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final Executor mCallbackExecutor; + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final SessionCallback mCallback; + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final Session2Link mSessionStub; + + private final String mSessionId; + private final PendingIntent mSessionActivity; + private final Session2Token mSessionToken; + private final MediaSessionManager mSessionManager; + private final Handler mResultHandler; + + //@GuardedBy("mLock") + @SuppressWarnings("WeakerAccess") /* synthetic access */ + private boolean mClosed; + + MediaSession2(@NonNull Context context, @NonNull String id, PendingIntent sessionActivity, + @NonNull Executor callbackExecutor, @NonNull SessionCallback callback) { + synchronized (MediaSession2.class) { + if (SESSION_ID_LIST.contains(id)) { + throw new IllegalStateException("Session ID must be unique. ID=" + id); + } + SESSION_ID_LIST.add(id); + } + + mContext = context; + mSessionId = id; + mSessionActivity = sessionActivity; + mCallbackExecutor = callbackExecutor; + mCallback = callback; + mSessionStub = new Session2Link(this); + mSessionToken = new Session2Token(Process.myUid(), TYPE_SESSION, context.getPackageName(), + mSessionStub); + mSessionManager = (MediaSessionManager) mContext.getSystemService( + Context.MEDIA_SESSION_SERVICE); + // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked. + mResultHandler = new Handler(context.getMainLooper()); + } + + @Override + public void close() { + try { + synchronized (MediaSession2.class) { + SESSION_ID_LIST.remove(mSessionId); + } + Collection<ControllerInfo> controllerInfos; + synchronized (mLock) { + controllerInfos = mConnectedControllers.values(); + mConnectedControllers.clear(); + mClosed = true; + } + for (ControllerInfo info : controllerInfos) { + info.notifyDisconnected(); + } + } catch (Exception e) { + // Should not be here. + } + } + + /** + * Returns the session ID + */ + @NonNull + public String getSessionId() { + return mSessionId; + } + + /** + * Returns the {@link Session2Token} for creating {@link MediaController2}. + */ + @NonNull + public Session2Token getSessionToken() { + return mSessionToken; + } + + /** + * Broadcasts a session command to all the connected controllers + * <p> + * @param command the session command + * @param args optional arguments + */ + public void broadcastSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) { + if (command == null) { + throw new IllegalArgumentException("command shouldn't be null"); + } + Collection<ControllerInfo> controllerInfos; + synchronized (mLock) { + controllerInfos = mConnectedControllers.values(); + } + for (ControllerInfo controller : controllerInfos) { + controller.sendSessionCommand(command, args, null); + } + } + + /** + * Sends a session command to a specific controller + * <p> + * @param controller the controller to get the session command + * @param command the session command + * @param args optional arguments + * @return a token which will be sent together in {@link SessionCallback#onCommandResult} + * when its result is received. + */ + public Object sendSessionCommand(@NonNull ControllerInfo controller, + @NonNull Session2Command command, @Nullable Bundle args) { + if (controller == null) { + throw new IllegalArgumentException("controller shouldn't be null"); + } + if (command == null) { + throw new IllegalArgumentException("command shouldn't be null"); + } + ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) { + protected void onReceiveResult(int resultCode, Bundle resultData) { + controller.receiveCommandResult(this); + mCallbackExecutor.execute(() -> { + mCallback.onCommandResult(MediaSession2.this, controller, this, + command, new Session2Command.Result(resultCode, resultData)); + }); + } + }; + controller.sendSessionCommand(command, args, resultReceiver); + return resultReceiver; + } + + /** + * Cancels the session command previously sent. + * + * @param controller the controller to get the session command + * @param token the token which is returned from {@link #sendSessionCommand}. + */ + public void cancelSessionCommand(ControllerInfo controller, Object token) { + if (token == null) { + throw new IllegalArgumentException("token shouldn't be null"); + } + controller.cancelSessionCommand(token); + } + + boolean isClosed() { + synchronized (mLock) { + return mClosed; + } + } + + // Called by Session2Link.onConnect + void onConnect(final Controller2Link controller, int seq, Bundle connectionRequest) { + if (controller == null || connectionRequest == null) { + return; + } + final int uid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + final long token = Binder.clearCallingIdentity(); + // Binder.getCallingPid() can be 0 for an oneway call from the remote process. + // If it's the case, use PID from the ConnectionRequest. + final int pid = (callingPid != 0) ? callingPid : connectionRequest.getInt(KEY_PID); + final String pkg = connectionRequest.getString(KEY_PACKAGE_NAME); + try { + RemoteUserInfo remoteUserInfo = new RemoteUserInfo(pkg, pid, uid); + final ControllerInfo controllerInfo = new ControllerInfo(remoteUserInfo, + mSessionManager.isTrustedForMediaControl(remoteUserInfo), controller); + mCallbackExecutor.execute(() -> { + if (isClosed()) { + return; + } + controllerInfo.mAllowedCommands = + mCallback.onConnect(MediaSession2.this, controllerInfo); + // Don't reject connection for the request from trusted app. + // Otherwise server will fail to retrieve session's information to dispatch + // media keys to. + boolean accept = + controllerInfo.mAllowedCommands != null || controllerInfo.isTrusted(); + if (accept) { + if (controllerInfo.mAllowedCommands == null) { + // For trusted apps, send non-null allowed commands to keep + // connection. + controllerInfo.mAllowedCommands = new Session2CommandGroup(); + } + if (DEBUG) { + Log.d(TAG, "Accepting connection: " + controllerInfo); + } + synchronized (mLock) { + if (mConnectedControllers.containsKey(controller)) { + Log.w(TAG, "Controller " + controllerInfo + " has sent connection" + + " request multiple times"); + } + mConnectedControllers.put(controller, controllerInfo); + } + // If connection is accepted, notify the current state to the controller. + // It's needed because we cannot call synchronous calls between + // session/controller. + Bundle connectionResult = new Bundle(); + connectionResult.putParcelable(KEY_SESSION2_STUB, mSessionStub); + connectionResult.putParcelable(KEY_ALLOWED_COMMANDS, + controllerInfo.mAllowedCommands); + + // Double check if session is still there, because close() can be called in + // another thread. + if (isClosed()) { + return; + } + controllerInfo.notifyConnected(connectionResult); + } else { + if (DEBUG) { + Log.d(TAG, "Rejecting connection, controllerInfo=" + controllerInfo); + } + controllerInfo.notifyDisconnected(); + } + }); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Called by Session2Link.onDisconnect + void onDisconnect(final Controller2Link controller, int seq) { + if (controller == null) { + return; + } + final ControllerInfo controllerInfo; + synchronized (mLock) { + controllerInfo = mConnectedControllers.get(controller); + } + if (controllerInfo == null) { + return; + } + + final long token = Binder.clearCallingIdentity(); + try { + mCallbackExecutor.execute(() -> { + mCallback.onDisconnected(MediaSession2.this, controllerInfo); + }); + mConnectedControllers.remove(controller); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Called by Session2Link.onSessionCommand + void onSessionCommand(final Controller2Link controller, final int seq, + final Session2Command command, final Bundle args, + @Nullable ResultReceiver resultReceiver) { + if (controller == null) { + return; + } + final ControllerInfo controllerInfo; + synchronized (mLock) { + controllerInfo = mConnectedControllers.get(controller); + } + if (controllerInfo == null) { + return; + } + + // TODO: check allowed commands. + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + controllerInfo.addRequestedCommandSeqNumber(seq); + } + + mCallbackExecutor.execute(() -> { + if (!controllerInfo.removeRequestedCommandSeqNumber(seq)) { + resultReceiver.send(RESULT_INFO_SKIPPED, null); + return; + } + Session2Command.Result result = mCallback.onSessionCommand( + MediaSession2.this, controllerInfo, command, args); + if (resultReceiver != null) { + if (result == null) { + throw new RuntimeException("onSessionCommand shouldn't return null"); + } else { + resultReceiver.send(result.getResultCode(), result.getResultData()); + } + } + }); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Called by Session2Link.onCancelCommand + void onCancelCommand(final Controller2Link controller, final int seq) { + final ControllerInfo controllerInfo; + synchronized (mLock) { + controllerInfo = mConnectedControllers.get(controller); + } + if (controllerInfo == null) { + return; + } + + final long token = Binder.clearCallingIdentity(); + try { + controllerInfo.removeRequestedCommandSeqNumber(seq); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + /** + * Builder for {@link MediaSession2}. + * <p> + * Any incoming event from the {@link MediaController2} will be handled on the callback + * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default. + */ + public static final class Builder { + private Context mContext; + private String mId; + private PendingIntent mSessionActivity; + private Executor mCallbackExecutor; + private SessionCallback mCallback; + + /** + * Creates a builder for {@link MediaSession2}. + * + * @param context Context + * @throws IllegalArgumentException if context is {@code null}. + */ + public Builder(@NonNull Context context) { + if (context == null) { + throw new IllegalArgumentException("context shouldn't be null"); + } + mContext = context; + } + + /** + * 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 Context#startActivity(Intent)}. + * + * @param pi The intent to launch to show UI for this session. + * @return The Builder to allow chaining + */ + @NonNull + public Builder setSessionActivity(@Nullable PendingIntent pi) { + mSessionActivity = pi; + return this; + } + + /** + * Set ID of the session. If it's not set, an empty string will be used to create a session. + * <p> + * Use this if and only if your app supports multiple playback at the same time and also + * wants to provide external apps to have finer controls of them. + * + * @param id id of the session. Must be unique per package. + * @throws IllegalArgumentException if id is {@code null}. + * @return The Builder to allow chaining + */ + @NonNull + public Builder setId(@NonNull String id) { + if (id == null) { + throw new IllegalArgumentException("id shouldn't be null"); + } + mId = id; + return this; + } + + /** + * Set callback for the session and its executor. + * + * @param executor callback executor + * @param callback session callback. + * @return The Builder to allow chaining + */ + @NonNull + public Builder setSessionCallback(@NonNull Executor executor, + @NonNull SessionCallback callback) { + mCallbackExecutor = executor; + mCallback = callback; + return this; + } + + /** + * Build {@link MediaSession2}. + * + * @return a new session + * @throws IllegalStateException if the session with the same id is already exists for the + * package. + */ + @NonNull + public MediaSession2 build() { + if (mCallbackExecutor == null) { + mCallbackExecutor = mContext.getMainExecutor(); + } + if (mCallback == null) { + mCallback = new SessionCallback() {}; + } + if (mId == null) { + mId = ""; + } + return new MediaSession2(mContext, mId, mSessionActivity, mCallbackExecutor, mCallback); + } + } + + /** + * Information of a controller. + * <p> + * This API is not generally intended for third party application developers. + */ + public static final class ControllerInfo { + private final RemoteUserInfo mRemoteUserInfo; + private final boolean mIsTrusted; + private final Controller2Link mControllerBinder; + private final Object mLock = new Object(); + //@GuardedBy("mLock") + private int mNextSeqNumber; + //@GuardedBy("mLock") + private ArrayMap<ResultReceiver, Integer> mPendingCommands; + //@GuardedBy("mLock") + private ArraySet<Integer> mRequestedCommandSeqNumbers; + + @SuppressWarnings("WeakerAccess") /* synthetic access */ + Session2CommandGroup mAllowedCommands; + + /** + * @param remoteUserInfo remote user info + * @param trusted {@code true} if trusted, {@code false} otherwise + * @param controllerBinder Controller2Link for the connected controller. + */ + ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted, + @Nullable Controller2Link controllerBinder) { + mRemoteUserInfo = remoteUserInfo; + mIsTrusted = trusted; + mControllerBinder = controllerBinder; + mPendingCommands = new ArrayMap<>(); + mRequestedCommandSeqNumbers = new ArraySet<>(); + } + + /** + * @return remote user info of the controller. + */ + @NonNull + public RemoteUserInfo getRemoteUserInfo() { + return mRemoteUserInfo; + } + + /** + * @return package name of the controller. + */ + @NonNull + public String getPackageName() { + return mRemoteUserInfo.getPackageName(); + } + + /** + * @return uid of the controller. Can be a negative value if the uid cannot be obtained. + */ + public int getUid() { + return mRemoteUserInfo.getUid(); + } + + /** + * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or + * has a enabled notification listener so can be trusted to accept connection and incoming + * command request. + * + * @return {@code true} if the controller is trusted. + * @hide + */ + public boolean isTrusted() { + return mIsTrusted; + } + + @Override + public int hashCode() { + return Objects.hash(mControllerBinder, mRemoteUserInfo); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ControllerInfo)) return false; + if (this == obj) return true; + + ControllerInfo other = (ControllerInfo) obj; + if (mControllerBinder != null || other.mControllerBinder != null) { + return Objects.equals(mControllerBinder, other.mControllerBinder); + } + return mRemoteUserInfo.equals(other.mRemoteUserInfo); + } + + @Override + public String toString() { + return "ControllerInfo {pkg=" + mRemoteUserInfo.getPackageName() + ", uid=" + + mRemoteUserInfo.getUid() + ", allowedCommands=" + mAllowedCommands + "})"; + } + + void notifyConnected(Bundle connectionResult) { + if (mControllerBinder == null) return; + + try { + mControllerBinder.notifyConnected(getNextSeqNumber(), connectionResult); + } catch (RuntimeException e) { + // Controller may be died prematurely. + } + } + + void notifyDisconnected() { + if (mControllerBinder == null) return; + + try { + mControllerBinder.notifyDisconnected(getNextSeqNumber()); + } catch (RuntimeException e) { + // Controller may be died prematurely. + } + } + + void sendSessionCommand(Session2Command command, Bundle args, + ResultReceiver resultReceiver) { + if (mControllerBinder == null) return; + + try { + int seq = getNextSeqNumber(); + synchronized (mLock) { + mPendingCommands.put(resultReceiver, seq); + } + mControllerBinder.sendSessionCommand(seq, command, args, resultReceiver); + } catch (RuntimeException e) { + // Controller may be died prematurely. + synchronized (mLock) { + mPendingCommands.remove(resultReceiver); + } + resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null); + } + } + + void cancelSessionCommand(@NonNull Object token) { + if (mControllerBinder == null) return; + Integer seq; + synchronized (mLock) { + seq = mPendingCommands.remove(token); + } + if (seq != null) { + mControllerBinder.cancelSessionCommand(seq); + } + } + + void receiveCommandResult(ResultReceiver resultReceiver) { + synchronized (mLock) { + mPendingCommands.remove(resultReceiver); + } + } + + void addRequestedCommandSeqNumber(int seq) { + synchronized (mLock) { + mRequestedCommandSeqNumbers.add(seq); + } + } + + boolean removeRequestedCommandSeqNumber(int seq) { + synchronized (mLock) { + return mRequestedCommandSeqNumbers.remove(seq); + } + } + + private int getNextSeqNumber() { + synchronized (mLock) { + return mNextSeqNumber++; + } + } + } + + /** + * Callback to be called for all incoming commands from {@link MediaController2}s. + * <p> + * This API is not generally intended for third party application developers. + */ + public abstract static class SessionCallback { + /** + * Called when a controller is created for this session. Return allowed commands for + * controller. By default it allows all connection requests and commands. + * <p> + * You can reject the connection by returning {@code null}. In that case, controller + * receives {@link MediaController2.ControllerCallback#onDisconnected(MediaController2)} + * and cannot be used. + * + * @param session the session for this event + * @param controller controller information. + * @return allowed commands. Can be {@code null} to reject connection. + */ + @Nullable + public Session2CommandGroup onConnect(@NonNull MediaSession2 session, + @NonNull ControllerInfo controller) { + Session2CommandGroup commands = new Session2CommandGroup.Builder() + .addAllPredefinedCommands(Session2Command.COMMAND_VERSION_1) + .build(); + return commands; + } + + /** + * Called when a controller is disconnected + * + * @param session the session for this event + * @param controller controller information + */ + public void onDisconnected(@NonNull MediaSession2 session, + @NonNull ControllerInfo controller) { } + + /** + * Called when a controller sent a session command. + * + * @param session the session for this event + * @param controller controller information + * @param command the session command + * @param args optional arguments + * @return the result for the session command. A runtime exception will be thrown if null + * is returned. + */ + @NonNull + public Session2Command.Result onSessionCommand(@NonNull MediaSession2 session, + @NonNull ControllerInfo controller, @NonNull Session2Command command, + @Nullable Bundle args) { + return null; + } + + /** + * Called when the command sent to the controller is finished. + * + * @param session the session for this event + * @param controller controller information + * @param token the token got from {@link MediaSession2#sendSessionCommand} + * @param command the session command + * @param result the result of the session command + */ + public void onCommandResult(@NonNull MediaSession2 session, + @NonNull ControllerInfo controller, @NonNull Object token, + @NonNull Session2Command command, @NonNull Session2Command.Result result) { } + } +} diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index 84dfcb13083f..42597aa0141c 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -16,6 +16,7 @@ package android.media; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; @@ -60,6 +61,8 @@ public class Ringtone { private final Context mContext; private final AudioManager mAudioManager; + private VolumeShaper.Configuration mVolumeShaperConfig; + private VolumeShaper mVolumeShaper; /** * Flag indicating if we're allowed to fall back to remote playback using @@ -302,6 +305,18 @@ public class Ringtone { */ @UnsupportedAppUsage public void setUri(Uri uri) { + setUri(uri, null); + } + + /** + * Set {@link Uri} to be used for ringtone playback. Attempts to open + * locally, otherwise will delegate playback to remote + * {@link IRingtonePlayer}. Add {@link VolumeShaper} if required. + * + * @hide + */ + public void setUri(Uri uri, @Nullable VolumeShaper.Configuration volumeShaperConfig) { + mVolumeShaperConfig = volumeShaperConfig; destroyLocalPlayer(); mUri = uri; @@ -319,6 +334,9 @@ public class Ringtone { synchronized (mPlaybackSettingsLock) { applyPlaybackProperties_sync(); } + if (mVolumeShaperConfig != null) { + mVolumeShaper = mLocalPlayer.createVolumeShaper(mVolumeShaperConfig); + } mLocalPlayer.prepare(); } catch (SecurityException | IOException e) { @@ -412,6 +430,9 @@ public class Ringtone { } mLocalPlayer.setOnCompletionListener(mCompletionListener); mLocalPlayer.start(); + if (mVolumeShaper != null) { + mVolumeShaper.apply(VolumeShaper.Operation.PLAY); + } } /** @@ -458,6 +479,9 @@ public class Ringtone { synchronized (mPlaybackSettingsLock) { applyPlaybackProperties_sync(); } + if (mVolumeShaperConfig != null) { + mVolumeShaper = mLocalPlayer.createVolumeShaper(mVolumeShaperConfig); + } mLocalPlayer.prepare(); startLocalPlayer(); afd.close(); diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 874f21ea8c28..0679e8e90e85 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -694,6 +694,27 @@ public class RingtoneManager { return getRingtone(context, ringtoneUri, -1); } + /** + * Returns a {@link Ringtone} with {@link VolumeShaper} if required for a given sound URI. + * <p> + * If the given URI cannot be opened for any reason, this method will + * attempt to fallback on another sound. If it cannot find any, it will + * return null. + * + * @param context A context used to query. + * @param ringtoneUri The {@link Uri} of a sound or ringtone. + * @param volumeShaperConfig config for volume shaper of the ringtone if applied. + * @return A {@link Ringtone} for the given URI, or null. + * + * @hide + */ + public static Ringtone getRingtone( + final Context context, Uri ringtoneUri, + @Nullable VolumeShaper.Configuration volumeShaperConfig) { + // Don't set the stream type + return getRingtone(context, ringtoneUri, -1 /* streamType */, volumeShaperConfig); + } + //FIXME bypass the notion of stream types within the class /** * Returns a {@link Ringtone} for a given sound URI on the given stream @@ -707,13 +728,32 @@ public class RingtoneManager { */ @UnsupportedAppUsage private static Ringtone getRingtone(final Context context, Uri ringtoneUri, int streamType) { + return getRingtone(context, ringtoneUri, streamType, null /* volumeShaperConfig */); + } + + //FIXME bypass the notion of stream types within the class + /** + * Returns a {@link Ringtone} with {@link VolumeShaper} if required for a given sound URI on + * the given stream type. Normally, if you change the stream type on the returned + * {@link Ringtone}, it will re-create the {@link MediaPlayer}. This is just + * an optimized route to avoid that. + * + * @param streamType The stream type for the ringtone, or -1 if it should + * not be set (and the default used instead). + * @param volumeShaperConfig config for volume shaper of the ringtone if applied. + * @see #getRingtone(Context, Uri) + */ + @UnsupportedAppUsage + private static Ringtone getRingtone( + final Context context, Uri ringtoneUri, int streamType, + @Nullable VolumeShaper.Configuration volumeShaperConfig) { try { final Ringtone r = new Ringtone(context, true); if (streamType >= 0) { //FIXME deprecated call r.setStreamType(streamType); } - r.setUri(ringtoneUri); + r.setUri(ringtoneUri, volumeShaperConfig); return r; } catch (Exception ex) { Log.e(TAG, "Failed to open ringtone " + ringtoneUri + ": " + ex); diff --git a/media/java/android/media/Session2Command.aidl b/media/java/android/media/Session2Command.aidl new file mode 100644 index 000000000000..43a7b123ed29 --- /dev/null +++ b/media/java/android/media/Session2Command.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +parcelable Session2Command; diff --git a/media/java/android/media/Session2Command.java b/media/java/android/media/Session2Command.java new file mode 100644 index 000000000000..e46e64eb1a5c --- /dev/null +++ b/media/java/android/media/Session2Command.java @@ -0,0 +1,735 @@ +/* + * 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.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; +import android.util.ArrayMap; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.Objects; + +/** + * Define a command that a {@link MediaController2} can send to a {@link MediaSession2}. + * <p> + * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command. + * If {@link #getCommandCode()} is {@link #COMMAND_CODE_CUSTOM}), it's custom command and + * {@link #getCustomCommand()} shouldn't be {@code null}. + * <p> + * This API is not generally intended for third party application developers. + * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> + * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> + * for consistent behavior across all devices. + * </p> + * @hide + */ +public final class Session2Command implements Parcelable { + /** + * The first version of session commands. This version is for commands introduced in API 29. + * <p> + * This would be used to specify which commands should be added by + * {@link Session2CommandGroup.Builder#addAllPredefinedCommands(int)} + * + * @see Session2CommandGroup.Builder#addAllPredefinedCommands(int) + */ + public static final int COMMAND_VERSION_1 = 1; + + /** + * @hide + */ + public static final int COMMAND_VERSION_CURRENT = COMMAND_VERSION_1; + + /** + * @hide + */ + @IntDef({COMMAND_VERSION_1}) + @Retention(RetentionPolicy.SOURCE) + public @interface CommandVersion {} + + /** + * @hide + */ + @IntDef({COMMAND_CODE_CUSTOM, + COMMAND_CODE_PLAYER_PLAY, + COMMAND_CODE_PLAYER_PAUSE, + COMMAND_CODE_PLAYER_PREPARE, + COMMAND_CODE_PLAYER_SEEK_TO, + COMMAND_CODE_PLAYER_SET_SPEED, + COMMAND_CODE_PLAYER_GET_PLAYLIST, + COMMAND_CODE_PLAYER_SET_PLAYLIST, + COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM, + COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM, + COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM, + COMMAND_CODE_PLAYER_SET_SHUFFLE_MODE, + COMMAND_CODE_PLAYER_SET_REPEAT_MODE, + COMMAND_CODE_PLAYER_GET_PLAYLIST_METADATA, + COMMAND_CODE_PLAYER_ADD_PLAYLIST_ITEM, + COMMAND_CODE_PLAYER_REMOVE_PLAYLIST_ITEM, + COMMAND_CODE_PLAYER_REPLACE_PLAYLIST_ITEM, + COMMAND_CODE_PLAYER_GET_CURRENT_MEDIA_ITEM, + COMMAND_CODE_PLAYER_UPDATE_LIST_METADATA, + COMMAND_CODE_PLAYER_SET_MEDIA_ITEM, + COMMAND_CODE_VOLUME_SET_VOLUME, + COMMAND_CODE_VOLUME_ADJUST_VOLUME, + COMMAND_CODE_SESSION_FAST_FORWARD, + COMMAND_CODE_SESSION_REWIND, + COMMAND_CODE_SESSION_SKIP_FORWARD, + COMMAND_CODE_SESSION_SKIP_BACKWARD, + COMMAND_CODE_SESSION_SET_RATING, + COMMAND_CODE_LIBRARY_GET_LIBRARY_ROOT, + COMMAND_CODE_LIBRARY_SUBSCRIBE, + COMMAND_CODE_LIBRARY_UNSUBSCRIBE, + COMMAND_CODE_LIBRARY_GET_CHILDREN, + COMMAND_CODE_LIBRARY_GET_ITEM, + COMMAND_CODE_LIBRARY_SEARCH, + COMMAND_CODE_LIBRARY_GET_SEARCH_RESULT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CommandCode {} + + /** + * Command code for the custom command which can be defined by string action in the + * {@link Session2Command}. + */ + public static final int COMMAND_CODE_CUSTOM = 0; + + //////////////////////////////////////////////////////////////////////////////////////////////// + // Player commands (i.e. commands to {@link Session2Player}) + //////////////////////////////////////////////////////////////////////////////////////////////// + static final ArrayMap<Integer, Range> VERSION_PLAYER_COMMANDS_MAP = new ArrayMap<>(); + static final ArrayMap<Integer, Range> VERSION_PLAYER_PLAYLIST_COMMANDS_MAP = new ArrayMap<>(); + + // TODO: check the link tag, and reassign int values properly. + /** + * Command code for {@link MediaController2#play()}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, + * Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_PLAY = 10000; + + /** + * Command code for {@link MediaController2#pause()}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, + * Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_PAUSE = 10001; + + /** + * Command code for {@link MediaController2#prepare()}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, + * Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_PREPARE = 10002; + + /** + * Command code for {@link MediaController2#seekTo(long)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, + * Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SEEK_TO = 10003; + + /** + * Command code for {@link MediaController2#setPlaybackSpeed(float)}}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the {@link Session22Callback#onCommandRequest(MediaSession2, Controller2Info, + * Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SET_SPEED = 10004; + + /** + * Command code for {@link MediaController2#getPlaylist()}. This will expose metadata + * information to the controller. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_GET_PLAYLIST = 10005; + + /** + * Command code for {@link MediaController2#setPlaylist(List, MediaMetadata)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SET_PLAYLIST = 10006; + + /** + * Command code for {@link MediaController2#skipToPlaylistItem(int)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM = 10007; + + /** + * Command code for {@link MediaController2#skipToPreviousPlaylistItem()}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the {@link Session2Callback#onCommandRequest( + * MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM = 10008; + + /** + * Command code for {@link MediaController2#skipToNextPlaylistItem()}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the {@link Session2Callback#onCommandRequest( + * MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + + public static final int COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM = 10009; + + /** + * Command code for {@link MediaController2#setShuffleMode(int)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SET_SHUFFLE_MODE = 10010; + + /** + * Command code for {@link MediaController2#setRepeatMode(int)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SET_REPEAT_MODE = 10011; + + /** + * Command code for {@link MediaController2#getPlaylistMetadata()}. This will expose metadata + * information to the controller. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_GET_PLAYLIST_METADATA = 10012; + + /** + * Command code for {@link MediaController2#addPlaylistItem(int, String)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_ADD_PLAYLIST_ITEM = 10013; + + /** + * Command code for {@link MediaController2#removePlaylistItem(int, String)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_REMOVE_PLAYLIST_ITEM = 10014; + + /** + * Command code for {@link MediaController2#replacePlaylistItem(int, String)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_REPLACE_PLAYLIST_ITEM = 10015; + + /** + * Command code for {@link MediaController2#getCurrentMediaItem()}. This will expose metadata + * information to the controller. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_GET_CURRENT_MEDIA_ITEM = 10016; + + /** + * Command code for {@link MediaController2#updatePlaylistMetadata(MediaMetadata)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_UPDATE_LIST_METADATA = 10017; + + /** + * Command code for {@link MediaController2#setMediaItem(String)}. + * <p> + * Command would be sent directly to the player if the session doesn't reject the request + * through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_PLAYER_SET_MEDIA_ITEM = 10018; + + static { + VERSION_PLAYER_COMMANDS_MAP.put(COMMAND_VERSION_1, + new Range(COMMAND_CODE_PLAYER_PLAY, COMMAND_CODE_PLAYER_SET_MEDIA_ITEM)); + } + + static { + VERSION_PLAYER_PLAYLIST_COMMANDS_MAP.put(COMMAND_VERSION_1, + new Range(COMMAND_CODE_PLAYER_GET_PLAYLIST, + COMMAND_CODE_PLAYER_SET_MEDIA_ITEM)); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + // Volume commands (i.e. commands to {@link AudioManager} or {@link RouteMediaPlayer}) + //////////////////////////////////////////////////////////////////////////////////////////////// + static final ArrayMap<Integer, Range> VERSION_VOLUME_COMMANDS_MAP = new ArrayMap<>(); + + /** + * Command code for {@link MediaController2#setVolumeTo(int, int)}. + * <p> + * <p> + * If the session doesn't reject the request through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}, + * command would adjust the device volume. It would send to the player directly only if it's + * remote player. See RouteMediaPlayer for a remote player. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_VOLUME_SET_VOLUME = 30000; + + /** + * Command code for {@link MediaController2#adjustVolume(int, int)}. + * <p> + * If the session doesn't reject the request through the + * {@link Session2Callback#onCommandRequest(MediaSession2, Controller2Info, Session2Command)}, + * command would adjust the device volume. It would send to the player directly only if it's + * remote player. See RouteMediaPlayer for a remote player. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_VOLUME_ADJUST_VOLUME = 30001; + + static { + VERSION_VOLUME_COMMANDS_MAP.put(COMMAND_VERSION_1, + new Range(COMMAND_CODE_VOLUME_SET_VOLUME, + COMMAND_CODE_VOLUME_ADJUST_VOLUME)); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + // Session commands (i.e. commands to {@link MediaSession2#Session2Callback}) + //////////////////////////////////////////////////////////////////////////////////////////////// + static final ArrayMap<Integer, Range> VERSION_SESSION_COMMANDS_MAP = new ArrayMap<>(); + + /** + * Command code for {@link MediaController2#fastForward()}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_SESSION_FAST_FORWARD = 40000; + + /** + * Command code for {@link MediaController2#rewind()}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_SESSION_REWIND = 40001; + + /** + * Command code for {@link MediaController2#skipForward()}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_SESSION_SKIP_FORWARD = 40002; + + /** + * Command code for {@link MediaController2#skipBackward()}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_SESSION_SKIP_BACKWARD = 40003; + + /** + * Command code for {@link MediaController2#setRating(String, Rating)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_SESSION_SET_RATING = 40010; + + /** + * @hide + */ + @IntDef(flag = false, /*prefix = "RESULT_CODE",*/ value = { + RESULT_SUCCESS, + RESULT_ERROR_UNKNOWN_ERROR, + RESULT_ERROR_INVALID_STATE, + RESULT_ERROR_BAD_VALUE, + RESULT_ERROR_PERMISSION_DENIED, + RESULT_ERROR_IO_ERROR, + RESULT_INFO_SKIPPED, + RESULT_ERROR_SESSION_DISCONNECTED, + RESULT_ERROR_NOT_SUPPORTED, + RESULT_ERROR_SESSION_AUTHENTICATION_EXPIRED, + RESULT_ERROR_SESSION_PREMIUM_ACCOUNT_REQUIRED, + RESULT_ERROR_SESSION_CONCURRENT_STREAM_LIMIT, + RESULT_ERROR_SESSION_PARENTAL_CONTROL_RESTRICTED, + RESULT_ERROR_SESSION_NOT_AVAILABLE_IN_REGION, + RESULT_ERROR_SESSION_SKIP_LIMIT_REACHED, + RESULT_ERROR_SESSION_SETUP_REQUIRED}) + @Retention(RetentionPolicy.SOURCE) + public @interface ResultCode {} + + /** + * 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; + + /** + * Result code representing that the command cannot be completed because the current state is + * not valid for the command. + */ + public static final int RESULT_ERROR_INVALID_STATE = -2; + + /** + * Result code representing that an argument is illegal. + */ + public static final int RESULT_ERROR_BAD_VALUE = -3; + + /** + * Result code representing that the command is not allowed. + */ + public static final int RESULT_ERROR_PERMISSION_DENIED = -4; + + /** + * Result code representing a file or network related command error. + */ + public static final int RESULT_ERROR_IO_ERROR = -5; + + /** + * Result code representing that the command is not supported nor implemented. + */ + public static final int RESULT_ERROR_NOT_SUPPORTED = -6; + + /** + * Result code representing that the session and controller were disconnected. + */ + public static final int RESULT_ERROR_SESSION_DISCONNECTED = -100; + + /** + * Result code representing that the authentication has expired. + */ + public static final int RESULT_ERROR_SESSION_AUTHENTICATION_EXPIRED = -102; + + /** + * Result code representing that a premium account is required. + */ + public static final int RESULT_ERROR_SESSION_PREMIUM_ACCOUNT_REQUIRED = -103; + + /** + * Result code representing that too many concurrent streams are detected. + */ + public static final int RESULT_ERROR_SESSION_CONCURRENT_STREAM_LIMIT = -104; + + /** + * Result code representing that the content is blocked due to parental controls. + */ + public static final int RESULT_ERROR_SESSION_PARENTAL_CONTROL_RESTRICTED = -105; + + /** + * Result code representing that the content is blocked due to being regionally unavailable. + */ + public static final int RESULT_ERROR_SESSION_NOT_AVAILABLE_IN_REGION = -106; + + /** + * Result code representing that the application cannot skip any more because the skip limit is + * reached. + */ + public static final int RESULT_ERROR_SESSION_SKIP_LIMIT_REACHED = -107; + + /** + * Result code representing that the session needs user's manual intervention. + */ + public static final int RESULT_ERROR_SESSION_SETUP_REQUIRED = -108; + + public static final Parcelable.Creator<Session2Command> CREATOR = + new Parcelable.Creator<Session2Command>() { + @Override + public Session2Command createFromParcel(Parcel in) { + return new Session2Command(in); + } + + @Override + public Session2Command[] newArray(int size) { + return new Session2Command[size]; + } + }; + + static { + VERSION_SESSION_COMMANDS_MAP.put(COMMAND_VERSION_1, + new Range(COMMAND_CODE_SESSION_FAST_FORWARD, COMMAND_CODE_SESSION_SET_RATING)); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + // Session commands (i.e. commands to {@link MediaLibrarySession#MediaLibrarySessionCallback}) + //////////////////////////////////////////////////////////////////////////////////////////////// + static final ArrayMap<Integer, Range> VERSION_LIBRARY_COMMANDS_MAP = new ArrayMap<>(); + + /** + * Command code for {@link MediaBrowser2#getLibraryRoot(Library2Params)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_LIBRARY_GET_LIBRARY_ROOT = 50000; + + /** + * Command code for {@link MediaBrowser2#subscribe(String, Library2Params)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_LIBRARY_SUBSCRIBE = 50001; + + /** + * Command code for {@link MediaBrowser2#unsubscribe(String)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_LIBRARY_UNSUBSCRIBE = 50002; + + /** + * Command code for {@link MediaBrowser2#getChildren(String, int, int, Library2Params)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_LIBRARY_GET_CHILDREN = 50003; + + /** + * Command code for {@link MediaBrowser2#getItem(String)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_LIBRARY_GET_ITEM = 50004; + + /** + * Command code for {@link MediaBrowser2#search(String, LibraryParams)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_LIBRARY_SEARCH = 50005; + + /** + * Command code for {@link MediaBrowser2#getSearchResult(String, int, int, Library2Params)}. + * <p> + * Code version is {@link #COMMAND_VERSION_1}. + */ + public static final int COMMAND_CODE_LIBRARY_GET_SEARCH_RESULT = 50006; + + static { + VERSION_LIBRARY_COMMANDS_MAP.put(COMMAND_VERSION_1, + new Range(COMMAND_CODE_LIBRARY_GET_LIBRARY_ROOT, + COMMAND_CODE_LIBRARY_GET_SEARCH_RESULT)); + } + + @CommandCode private final int mCommandCode; + // Nonnull if it's custom command + private final String mCustomCommand; + private final Bundle mExtras; + + /** + * Constructor for creating a predefined command. + * + * @param commandCode A command code for predefined command. + */ + public Session2Command(@CommandCode int commandCode) { + if (commandCode == COMMAND_CODE_CUSTOM) { + throw new IllegalArgumentException("commandCode shouldn't be COMMAND_CODE_CUSTOM"); + } + mCommandCode = commandCode; + mCustomCommand = null; + mExtras = null; + } + + /** + * Constructor for creating a custom command. + * + * @param action The action of this custom command. + * @param extras An extra bundle for this custom command. + */ + public Session2Command(@NonNull String action, @Nullable Bundle extras) { + if (action == null) { + throw new IllegalArgumentException("action shouldn't be null"); + } + mCommandCode = COMMAND_CODE_CUSTOM; + mCustomCommand = action; + mExtras = extras; + } + + /** + * Used by parcelable creator. + */ + @SuppressWarnings("WeakerAccess") /* synthetic access */ + Session2Command(Parcel in) { + mCommandCode = in.readInt(); + mCustomCommand = in.readString(); + mExtras = in.readBundle(); + } + + /** + * Gets the command code of a predefined command. + * This will return {@link #COMMAND_CODE_CUSTOM} for a custom command. + */ + public @CommandCode int getCommandCode() { + return mCommandCode; + } + + /** + * Gets the action of a custom command. + * This will return {@code null} for a predefined command. + */ + public @Nullable String getCustomCommand() { + return mCustomCommand; + } + + /** + * Gets the extra bundle of a custom command. + * This will return {@code null} for a predefined command. + */ + public @Nullable Bundle getExtras() { + return mExtras; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mCommandCode); + dest.writeString(mCustomCommand); + dest.writeBundle(mExtras); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Session2Command)) { + return false; + } + Session2Command other = (Session2Command) obj; + return mCommandCode == other.mCommandCode + && TextUtils.equals(mCustomCommand, other.mCustomCommand); + } + + @Override + public int hashCode() { + return Objects.hash(mCustomCommand, mCommandCode); + } + + /** + * Contains the result of {@link Session2Command}. + */ + public static final class Result { + private final int mResultCode; + private final Bundle mResultData; + + /** + * Constructor of {@link Result}. + * + * @param resultCode result code + * @param resultData result data + */ + public Result(int resultCode, Bundle resultData) { + mResultCode = resultCode; + mResultData = resultData; + } + + /** + * Returns the result code. + */ + public int getResultCode() { + return mResultCode; + } + + /** + * Returns the result data. + */ + public Bundle getResultData() { + return mResultData; + } + } + + @SuppressWarnings("WeakerAccess") /* synthetic access */ + static final class Range { + public final int lower; + public final int upper; + + Range(int lower, int upper) { + this.lower = lower; + this.upper = upper; + } + } +} + diff --git a/media/java/android/media/Session2CommandGroup.java b/media/java/android/media/Session2CommandGroup.java new file mode 100644 index 000000000000..18aff3007052 --- /dev/null +++ b/media/java/android/media/Session2CommandGroup.java @@ -0,0 +1,322 @@ +/* + * 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 static android.media.Session2Command.COMMAND_CODE_CUSTOM; +import static android.media.Session2Command.COMMAND_VERSION_1; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.media.Session2Command.Range; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * A set of {@link Session2Command} which represents a command group. + * <p> + * This API is not generally intended for third party application developers. + * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> + * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> + * for consistent behavior across all devices. + * </p> + * @hide + */ +public final class Session2CommandGroup implements Parcelable { + private static final String TAG = "Session2CommandGroup"; + + public static final Parcelable.Creator<Session2CommandGroup> CREATOR = + new Parcelable.Creator<Session2CommandGroup>() { + @Override + public Session2CommandGroup createFromParcel(Parcel in) { + return new Session2CommandGroup(in); + } + + @Override + public Session2CommandGroup[] newArray(int size) { + return new Session2CommandGroup[size]; + } + }; + + Set<Session2Command> mCommands = new HashSet<>(); + + /** + * Default Constructor. + */ + public Session2CommandGroup() { } + + /** + * Creates a new Session2CommandGroup with commands copied from another object. + * + * @param commands The collection of commands to copy. + */ + public Session2CommandGroup(@Nullable Collection<Session2Command> commands) { + if (commands != null) { + mCommands.addAll(commands); + } + } + + /** + * Used by parcelable creator. + */ + @SuppressWarnings("WeakerAccess") /* synthetic access */ + Session2CommandGroup(Parcel in) { + Session2Command[] commands = in.readParcelableArray( + Session2Command.class.getClassLoader(), Session2Command.class); + if (commands != null) { + for (Session2Command command : commands) { + mCommands.add(command); + } + } + } + + /** + * Adds a command to this command group. + * + * @param command A command to add. Shouldn't be {@code null}. + * @hide TODO remove this method + */ + public void addCommand(@NonNull Session2Command command) { + if (command == null) { + throw new IllegalArgumentException("command shouldn't be null"); + } + if (!hasCommand(command)) { + mCommands.add(command); + } + } + + /** + * Adds a predefined command with given {@code commandCode} to this command group. + * + * @param commandCode A command code to add. + * Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}. + * @hide TODO remove this method + */ + public void addCommand(@Session2Command.CommandCode int commandCode) { + if (commandCode == COMMAND_CODE_CUSTOM) { + throw new IllegalArgumentException( + "Use addCommand(Session2Command) for COMMAND_CODE_CUSTOM."); + } + if (!hasCommand(commandCode)) { + mCommands.add(new Session2Command(commandCode)); + } + } + + /** + * Checks whether this command group has a command that matches given {@code command}. + * + * @param command A command to find. Shouldn't be {@code null}. + */ + public boolean hasCommand(@NonNull Session2Command command) { + if (command == null) { + throw new IllegalArgumentException("command shouldn't be null"); + } + return mCommands.contains(command); + } + + /** + * Checks whether this command group has a command that matches given {@code commandCode}. + * + * @param commandCode A command code to find. + * Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}. + */ + public boolean hasCommand(@Session2Command.CommandCode int commandCode) { + if (commandCode == COMMAND_CODE_CUSTOM) { + throw new IllegalArgumentException("Use hasCommand(Command) for custom command"); + } + for (Session2Command command : mCommands) { + if (command.getCommandCode() == commandCode) { + return true; + } + } + return false; + } + + /** + * Gets all commands of this command group. + */ + public @NonNull Set<Session2Command> getCommands() { + return new HashSet<>(mCommands); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelableArray((Session2Command[]) mCommands.toArray(), 0); + } + + /** + * Builds a {@link Session2CommandGroup} object. + */ + public static final class Builder { + private Set<Session2Command> mCommands; + + public Builder() { + mCommands = new HashSet<>(); + } + + /** + * Creates a new builder for {@link Session2CommandGroup} with commands copied from another + * {@link Session2CommandGroup} object. + * @param commandGroup + */ + public Builder(@NonNull Session2CommandGroup commandGroup) { + mCommands = commandGroup.getCommands(); + } + + /** + * Adds a command to this command group. + * + * @param command A command to add. Shouldn't be {@code null}. + */ + public @NonNull Builder addCommand(@NonNull Session2Command command) { + if (command == null) { + throw new IllegalArgumentException("command shouldn't be null"); + } + mCommands.add(command); + return this; + } + + /** + * Adds a predefined command with given {@code commandCode} to this command group. + * + * @param commandCode A command code to add. + * Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}. + */ + public @NonNull Builder addCommand(@Session2Command.CommandCode int commandCode) { + if (commandCode == COMMAND_CODE_CUSTOM) { + throw new IllegalArgumentException( + "Use addCommand(Session2Command) for COMMAND_CODE_CUSTOM."); + } + mCommands.add(new Session2Command(commandCode)); + return this; + } + + /** + * Adds all predefined session commands except for the commands added after the specified + * version without default implementation. This provides convenient way to add commands + * with implementation. + * + * @param version command version + * @see Session2Command#COMMAND_VERSION_1 + * @see + * MediaSession2.Session2Callback#onConnect + */ + public @NonNull Builder addAllPredefinedCommands( + @Session2Command.CommandVersion int version) { + if (version != COMMAND_VERSION_1) { + throw new IllegalArgumentException("Unknown command version " + version); + } + addAllPlayerCommands(version); + addAllVolumeCommands(version); + addAllSessionCommands(version); + addAllLibraryCommands(version); + return this; + } + + /** + * Removes a command from this group which matches given {@code command}. + * + * @param command A command to find. Shouldn't be {@code null}. + */ + public @NonNull Builder removeCommand(@NonNull Session2Command command) { + if (command == null) { + throw new IllegalArgumentException("command shouldn't be null"); + } + mCommands.remove(command); + return this; + } + + /** + * Removes a command from this group which matches given {@code commandCode}. + * + * @param commandCode A command code to find. + * Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}. + */ + public @NonNull Builder removeCommand(@Session2Command.CommandCode int commandCode) { + if (commandCode == COMMAND_CODE_CUSTOM) { + throw new IllegalArgumentException("commandCode shouldn't be COMMAND_CODE_CUSTOM"); + } + mCommands.remove(new Session2Command(commandCode)); + return this; + } + + @NonNull Builder addAllPlayerCommands(@Session2Command.CommandVersion int version) { + addCommands(version, Session2Command.VERSION_PLAYER_COMMANDS_MAP); + return this; + } + + @NonNull Builder addAllPlayerCommands(@Session2Command.CommandVersion int version, + boolean includePlaylistCommands) { + if (includePlaylistCommands) { + return addAllPlayerCommands(version); + } + for (int i = COMMAND_VERSION_1; i <= version; i++) { + Range include = Session2Command.VERSION_PLAYER_COMMANDS_MAP.get(i); + Range exclude = Session2Command.VERSION_PLAYER_PLAYLIST_COMMANDS_MAP.get(i); + for (int code = include.lower; code <= include.upper; code++) { + if (code < exclude.lower && code > exclude.upper) { + addCommand(code); + } + } + } + return this; + } + + @NonNull Builder addAllVolumeCommands(@Session2Command.CommandVersion int version) { + addCommands(version, Session2Command.VERSION_VOLUME_COMMANDS_MAP); + return this; + } + + @NonNull Builder addAllSessionCommands(@Session2Command.CommandVersion int version) { + addCommands(version, Session2Command.VERSION_SESSION_COMMANDS_MAP); + return this; + } + + @NonNull Builder addAllLibraryCommands(@Session2Command.CommandVersion int version) { + addCommands(version, Session2Command.VERSION_LIBRARY_COMMANDS_MAP); + return this; + } + + private void addCommands( + @Session2Command.CommandVersion int version, ArrayMap<Integer, Range> map) { + for (int i = COMMAND_VERSION_1; i <= version; i++) { + Range range = map.get(i); + for (int code = range.lower; code <= range.upper; code++) { + addCommand(code); + } + } + } + + /** + * Builds {@link Session2CommandGroup}. + * + * @return a new {@link Session2CommandGroup}. + */ + public @NonNull Session2CommandGroup build() { + return new Session2CommandGroup(mCommands); + } + } +} diff --git a/media/java/android/media/Session2Link.java b/media/java/android/media/Session2Link.java new file mode 100644 index 000000000000..5fe558da12f5 --- /dev/null +++ b/media/java/android/media/Session2Link.java @@ -0,0 +1,190 @@ +/* + * 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.os.Bundle; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.RemoteException; +import android.os.ResultReceiver; +import android.util.Log; + +import java.util.Objects; + +/** + * Handles incoming commands from {@link MediaController2} to {@link MediaSession2}. + * @hide + */ +// @SystemApi +public final class Session2Link implements Parcelable { + private static final String TAG = "Session2Link"; + private static final boolean DEBUG = MediaSession2.DEBUG; + + public static final Parcelable.Creator<Session2Link> CREATOR = + new Parcelable.Creator<Session2Link>() { + @Override + public Session2Link createFromParcel(Parcel in) { + return new Session2Link(in); + } + + @Override + public Session2Link[] newArray(int size) { + return new Session2Link[size]; + } + }; + + private final MediaSession2 mSession; + private final IMediaSession2 mISession; + + public Session2Link(MediaSession2 session) { + mSession = session; + mISession = new Session2Stub(); + } + + Session2Link(Parcel in) { + mSession = null; + mISession = IMediaSession2.Stub.asInterface(in.readStrongBinder()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeStrongBinder(mISession.asBinder()); + } + + @Override + public int hashCode() { + return mISession.asBinder().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Session2Link)) { + return false; + } + Session2Link other = (Session2Link) obj; + return Objects.equals(mISession.asBinder(), other.mISession.asBinder()); + } + + /** Link to death with mISession */ + public void linkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) { + if (mISession != null) { + try { + mISession.asBinder().linkToDeath(recipient, flags); + } catch (RemoteException e) { + if (DEBUG) { + Log.d(TAG, "Session died too early.", e); + } + } + } + } + + /** Unlink to death with mISession */ + public boolean unlinkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) { + if (mISession != null) { + return mISession.asBinder().unlinkToDeath(recipient, flags); + } + return true; + } + + /** Interface method for IMediaSession2.connect */ + public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) { + try { + mISession.connect(caller, seq, connectionRequest); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaSession2.disconnect */ + public void disconnect(final Controller2Link caller, int seq) { + try { + mISession.disconnect(caller, seq); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaSession2.sendSessionCommand */ + public void sendSessionCommand(final Controller2Link caller, final int seq, + final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { + try { + mISession.sendSessionCommand(caller, seq, command, args, resultReceiver); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaSession2.sendSessionCommand */ + public void cancelSessionCommand(final Controller2Link caller, final int seq) { + try { + mISession.cancelSessionCommand(caller, seq); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Stub implementation for IMediaSession2.connect */ + public void onConnect(final Controller2Link caller, int seq, Bundle connectionRequest) { + mSession.onConnect(caller, seq, connectionRequest); + } + + /** Stub implementation for IMediaSession2.disconnect */ + public void onDisconnect(final Controller2Link caller, int seq) { + mSession.onDisconnect(caller, seq); + } + + /** Stub implementation for IMediaSession2.sendSessionCommand */ + public void onSessionCommand(final Controller2Link caller, final int seq, + final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { + mSession.onSessionCommand(caller, seq, command, args, resultReceiver); + } + + /** Stub implementation for IMediaSession2.cancelSessionCommand */ + public void onCancelCommand(final Controller2Link caller, final int seq) { + mSession.onCancelCommand(caller, seq); + } + + private class Session2Stub extends IMediaSession2.Stub { + @Override + public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) { + Session2Link.this.onConnect(caller, seq, connectionRequest); + } + + @Override + public void disconnect(final Controller2Link caller, int seq) { + Session2Link.this.onDisconnect(caller, seq); + } + + @Override + public void sendSessionCommand(final Controller2Link caller, final int seq, + final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { + Session2Link.this.onSessionCommand(caller, seq, command, args, resultReceiver); + } + + @Override + public void cancelSessionCommand(final Controller2Link caller, final int seq) { + Session2Link.this.onCancelCommand(caller, seq); + } + } +} diff --git a/media/java/android/media/Session2Token.java b/media/java/android/media/Session2Token.java new file mode 100644 index 000000000000..552cc0fad7de --- /dev/null +++ b/media/java/android/media/Session2Token.java @@ -0,0 +1,286 @@ +/* + * 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.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.Objects; + +/** + * Represents an ongoing {@link MediaSession2} or a {@link MediaSession2Service}. + * If it's representing a session service, it may not be ongoing. + * <p> + * This API is not generally intended for third party application developers. + * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> + * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> + * for consistent behavior across all devices. + * <p> + * This may be passed to apps by the session owner to allow them to create a + * {@link MediaController2} to communicate with the session. + * <p> + * It can be also obtained by {@link MediaSessionManager}. + * + * @hide + */ +// New version of MediaSession2.Token for following reasons +// - Stop implementing Parcelable for updatable support +// - Represent session and library service (formerly browser service) in one class. +// Previously MediaSession2.Token was for session and ComponentName was for service. +// This helps controller apps to keep target of dispatching media key events in uniform way. +// For details about the reason, see following. (Android O+) +// android.media.session.MediaSessionManager.Callback#onAddressedPlayerChanged +public final class Session2Token implements Parcelable { + private static final String TAG = "Session2Token"; + + public static final Creator<Session2Token> CREATOR = new Creator<Session2Token>() { + @Override + public Session2Token createFromParcel(Parcel p) { + return new Session2Token(p); + } + + @Override + public Session2Token[] newArray(int size) { + return new Session2Token[size]; + } + }; + + /** + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "TYPE_", value = {TYPE_SESSION, TYPE_SESSION_SERVICE, TYPE_LIBRARY_SERVICE}) + public @interface TokenType { + } + + /** + * Type for {@link MediaSession2}. + */ + public static final int TYPE_SESSION = 0; + + /** + * Type for {@link MediaSession2Service}. + */ + public static final int TYPE_SESSION_SERVICE = 1; + + /** + * Type for {@link MediaLibrary2Service}. + */ + public static final int TYPE_LIBRARY_SERVICE = 2; + + private final int mUid; + private final @TokenType int mType; + private final String mPackageName; + private final String mServiceName; + private final Session2Link mSessionLink; + private final ComponentName mComponentName; + + /** + * Constructor for the token. + * + * @param context The context. + * @param serviceComponent The component name of the service. + */ + public Session2Token(@NonNull Context context, @NonNull ComponentName serviceComponent) { + if (context == null) { + throw new IllegalArgumentException("context shouldn't be null"); + } + if (serviceComponent == null) { + throw new IllegalArgumentException("serviceComponent shouldn't be null"); + } + + final PackageManager manager = context.getPackageManager(); + final int uid = getUid(manager, serviceComponent.getPackageName()); + + // TODO: Uncomment below to stop hardcode type. + final int type = TYPE_SESSION; +// final int type; +// if (isInterfaceDeclared(manager, MediaLibraryService2.SERVICE_INTERFACE, +// serviceComponent)) { +// type = TYPE_LIBRARY_SERVICE; +// } else if (isInterfaceDeclared(manager, MediaSessionService2.SERVICE_INTERFACE, +// serviceComponent)) { +// type = TYPE_SESSION_SERVICE; +// } else if (isInterfaceDeclared(manager, +// MediaBrowserServiceCompat.SERVICE_INTERFACE, serviceComponent)) { +// type = TYPE_BROWSER_SERVICE_LEGACY; +// } else { +// throw new IllegalArgumentException(serviceComponent + " doesn't implement none of" +// + " MediaSessionService2, MediaLibraryService2, MediaBrowserService nor" +// + " MediaBrowserServiceCompat. Use service's full name."); +// } + mComponentName = serviceComponent; + mPackageName = serviceComponent.getPackageName(); + mServiceName = serviceComponent.getClassName(); + mUid = uid; + mType = type; + mSessionLink = null; + } + + Session2Token(int uid, int type, String packageName, Session2Link sessionLink) { + mUid = uid; + mType = type; + mPackageName = packageName; + mServiceName = null; + mComponentName = null; + mSessionLink = sessionLink; + } + + Session2Token(Parcel in) { + mUid = in.readInt(); + mType = in.readInt(); + mPackageName = in.readString(); + mServiceName = in.readString(); + // TODO: Uncomment below and stop hardcode mSessionLink + mSessionLink = null; + //mSessionLink = ISession.Stub.asInterface(in.readStrongBinder()); + mComponentName = ComponentName.unflattenFromString(in.readString()); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mUid); + dest.writeInt(mType); + dest.writeString(mPackageName); + dest.writeString(mServiceName); + // TODO: Uncomment below + //dest.writeStrongBinder(mSessionLink.getBinder()); + dest.writeString(mComponentName == null ? "" : mComponentName.flattenToString()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public int hashCode() { + return Objects.hash(mType, mUid, mPackageName, mServiceName, mSessionLink); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Session2Token)) { + return false; + } + Session2Token other = (Session2Token) obj; + return mUid == other.mUid + && TextUtils.equals(mPackageName, other.mPackageName) + && TextUtils.equals(mServiceName, other.mServiceName) + && mType == other.mType + && Objects.equals(mSessionLink, other.mSessionLink); + } + + @Override + public String toString() { + return "Session2Token {pkg=" + mPackageName + " type=" + mType + + " service=" + mServiceName + " Session2Link=" + mSessionLink + "}"; + } + + /** + * @return uid of the session + */ + public int getUid() { + return mUid; + } + + /** + * @return package name of the session + */ + @NonNull + public String getPackageName() { + return mPackageName; + } + + /** + * @return service name of the session. Can be {@code null} for {@link #TYPE_SESSION}. + */ + @Nullable + public String getServiceName() { + return mServiceName; + } + + /** + * @hide + * @return component name of the session. Can be {@code null} for {@link #TYPE_SESSION}. + */ + public ComponentName getComponentName() { + return mComponentName; + } + + /** + * @return type of the token + * @see #TYPE_SESSION + * @see #TYPE_SESSION_SERVICE + * @see #TYPE_LIBRARY_SERVICE + */ + public @TokenType int getType() { + return mType; + } + + /** + * @hide + */ + public Session2Link getSessionLink() { + return mSessionLink; + } + + private static boolean isInterfaceDeclared(PackageManager manager, String serviceInterface, + ComponentName serviceComponent) { + Intent serviceIntent = new Intent(serviceInterface); + // Use queryIntentServices to find services with MediaLibraryService2.SERVICE_INTERFACE. + // We cannot use resolveService with intent specified class name, because resolveService + // ignores actions if Intent.setClassName() is specified. + serviceIntent.setPackage(serviceComponent.getPackageName()); + + List<ResolveInfo> list = manager.queryIntentServices( + serviceIntent, PackageManager.GET_META_DATA); + if (list != null) { + for (int i = 0; i < list.size(); i++) { + ResolveInfo resolveInfo = list.get(i); + if (resolveInfo == null || resolveInfo.serviceInfo == null) { + continue; + } + if (TextUtils.equals( + resolveInfo.serviceInfo.name, serviceComponent.getClassName())) { + return true; + } + } + } + return false; + } + + private static int getUid(PackageManager manager, String packageName) { + try { + return manager.getApplicationInfo(packageName, 0).uid; + } catch (PackageManager.NameNotFoundException e) { + throw new IllegalArgumentException("Cannot find package " + packageName); + } + } +} diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java index f07076ad14aa..ccf49bd774a8 100644 --- a/media/java/android/media/ThumbnailUtils.java +++ b/media/java/android/media/ThumbnailUtils.java @@ -36,6 +36,7 @@ import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.net.Uri; +import android.os.Build; import android.os.CancellationSignal; import android.os.Environment; import android.os.ParcelFileDescriptor; @@ -362,27 +363,27 @@ public class ThumbnailUtils { } @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { return 1; } @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { return 1; } @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static void closeSilently(ParcelFileDescriptor c) { IoUtils.closeQuietly(c); } @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static ParcelFileDescriptor makeInputStream( Uri uri, ContentResolver cr) { try { @@ -396,7 +397,7 @@ public class ThumbnailUtils { * Transform source Bitmap to targeted width and height. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static Bitmap transform(Matrix scaler, Bitmap source, int targetWidth, @@ -502,7 +503,7 @@ public class ThumbnailUtils { } @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static void createThumbnailFromEXIF(String filePath, int targetSize, int maxPixels, SizedThumbnailBitmap sizedThumbBitmap) { } diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index 7fb3aa6d79f9..1c6210e0c060 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -165,6 +165,20 @@ public class AudioMix { } /** @hide */ + public boolean isRoutedToDevice(int deviceType, @NonNull String deviceAddress) { + if ((mRouteFlags & ROUTE_FLAG_RENDER) != ROUTE_FLAG_RENDER) { + return false; + } + if (deviceType != mDeviceSystemType) { + return false; + } + if (!deviceAddress.equals(mDeviceAddress)) { + return false; + } + return true; + } + + /** @hide */ @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index 6103f55745f9..65f3294800f5 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -22,6 +22,7 @@ import android.annotation.SystemApi; import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioAttributes; +import android.media.AudioDeviceInfo; import android.media.AudioFocusInfo; import android.media.AudioFormat; import android.media.AudioManager; @@ -323,6 +324,80 @@ public class AudioPolicy { } } + /** + * @hide + * Configures the audio framework so that all audio stream originating from the given UID + * can only come from a set of audio devices. + * For this routing to be operational, a number of {@link AudioMix} instances must have been + * previously registered on this policy, and routed to a super-set of the given audio devices + * with {@link AudioMix.Builder#setDevice(android.media.AudioDeviceInfo)}. Note that having + * multiple devices in the list doesn't imply the signals will be duplicated on the different + * audio devices, final routing will depend on the {@link AudioAttributes} of the sounds being + * played. + * @param uid UID of the application to affect. + * @param devices list of devices to which the audio stream of the application may be routed. + * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR} + * otherwise. + */ + @SystemApi + public int setUidDeviceAffinity(int uid, @NonNull List<AudioDeviceInfo> devices) { + if (devices == null) { + throw new IllegalArgumentException("Illegal null list of audio devices"); + } + synchronized (mLock) { + if (mStatus != POLICY_STATUS_REGISTERED) { + throw new IllegalStateException("Cannot use unregistered AudioPolicy"); + } + final int[] deviceTypes = new int[devices.size()]; + final String[] deviceAdresses = new String[devices.size()]; + int i = 0; + for (AudioDeviceInfo device : devices) { + if (device == null) { + throw new IllegalArgumentException( + "Illegal null AudioDeviceInfo in setUidDeviceAffinity"); + } + deviceTypes[i] = + AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType()); + deviceAdresses[i] = device.getAddress(); + i++; + } + final IAudioService service = getService(); + try { + final int status = service.setUidDeviceAffinity(this.cb(), + uid, deviceTypes, deviceAdresses); + return status; + } catch (RemoteException e) { + Log.e(TAG, "Dead object in setUidDeviceAffinity", e); + return AudioManager.ERROR; + } + } + } + + /** + * @hide + * Removes audio device affinity previously set by + * {@link #setUidDeviceAffinity(int, java.util.List)}. + * @param uid UID of the application affected. + * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR} + * otherwise. + */ + @SystemApi + public int removeUidDeviceAffinity(int uid) { + synchronized (mLock) { + if (mStatus != POLICY_STATUS_REGISTERED) { + throw new IllegalStateException("Cannot use unregistered AudioPolicy"); + } + final IAudioService service = getService(); + try { + final int status = service.removeUidDeviceAffinity(this.cb(), uid); + return status; + } catch (RemoteException e) { + Log.e(TAG, "Dead object in removeUidDeviceAffinity", e); + return AudioManager.ERROR; + } + } + } + public void setRegistration(String regId) { synchronized (mLock) { mRegistrationId = regId; diff --git a/media/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/session/ControllerCallbackLink.aidl new file mode 100644 index 000000000000..788f5d35d72b --- /dev/null +++ b/media/java/android/media/session/ControllerCallbackLink.aidl @@ -0,0 +1,18 @@ +/* + * 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.session; + +parcelable ControllerCallbackLink; diff --git a/media/java/android/media/session/ControllerCallbackLink.java b/media/java/android/media/session/ControllerCallbackLink.java new file mode 100644 index 000000000000..19da7cefe2db --- /dev/null +++ b/media/java/android/media/session/ControllerCallbackLink.java @@ -0,0 +1,240 @@ +/* + * 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.session; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.media.AudioAttributes; +import android.media.MediaMetadata; +import android.media.session.MediaSession.QueueItem; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.RemoteException; + +import java.util.List; + +/** + * Handles incoming commands to {@link MediaController.Callback}. + * @hide + */ +@SystemApi +public final class ControllerCallbackLink implements Parcelable { + CallbackStub mCallbackStub; + ISessionControllerCallback mIControllerCallback; + + /** + * Creator for stub (Callee) + */ + public ControllerCallbackLink(@NonNull CallbackStub callbackStub) { + mCallbackStub = callbackStub; + mIControllerCallback = new CallbackStubProxy(); + } + + /** + * Creator for interface (Caller) + */ + ControllerCallbackLink(Parcel in) { + mCallbackStub = null; + mIControllerCallback = ISessionControllerCallback.Stub.asInterface(in.readStrongBinder()); + } + + /** Interface method for ISessionControllerCallback.notifySessionDestroyed */ + public void notifySessionDestroyed() { + try { + mIControllerCallback.notifySessionDestroyed(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionControllerCallback.notifyEvent */ + public void notifyEvent(String event, Bundle extras) { + try { + mIControllerCallback.notifyEvent(event, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionControllerCallback.notifyPlaybackStateChanged */ + public void notifyPlaybackStateChanged(PlaybackState state) { + try { + mIControllerCallback.notifyPlaybackStateChanged(state); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionControllerCallback.notifyMetadataChanged */ + public void notifyMetadataChanged(MediaMetadata metadata) { + try { + mIControllerCallback.notifyMetadataChanged(metadata); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionControllerCallback.notifyQueueChanged */ + public void notifyQueueChanged(List<QueueItem> queue) { + try { + mIControllerCallback.notifyQueueChanged(queue); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionControllerCallback.notifyQueueTitleChanged */ + public void notifyQueueTitleChanged(CharSequence title) { + try { + mIControllerCallback.notifyQueueTitleChanged(title); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionControllerCallback.notifyExtrasChanged */ + public void notifyExtrasChanged(Bundle extras) { + try { + mIControllerCallback.notifyExtrasChanged(extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionControllerCallback.notifyVolumeInfoChanged */ + public void notifyVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType, + int maxVolume, int currentVolume) { + try { + mIControllerCallback.notifyVolumeInfoChanged(volumeType, attrs, controlType, maxVolume, + currentVolume); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Gets the binder */ + public IBinder getBinder() { + return mIControllerCallback.asBinder(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeStrongBinder(mIControllerCallback.asBinder()); + } + + public static final Parcelable.Creator<ControllerCallbackLink> CREATOR = + new Parcelable.Creator<ControllerCallbackLink>() { + @Override + public ControllerCallbackLink createFromParcel(Parcel in) { + return new ControllerCallbackLink(in); + } + + @Override + public ControllerCallbackLink[] newArray(int size) { + return new ControllerCallbackLink[size]; + } + }; + + /** + * Class for Stub implementation + */ + public abstract static class CallbackStub { + /** Stub method for ISessionControllerCallback.notifySessionDestroyed */ + public void onSessionDestroyed() { + } + + /** Stub method for ISessionControllerCallback.notifyEvent */ + public void onEvent(String event, Bundle extras) { + } + + /** Stub method for ISessionControllerCallback.notifyPlaybackStateChanged */ + public void onPlaybackStateChanged(PlaybackState state) { + } + + /** Stub method for ISessionControllerCallback.notifyMetadataChanged */ + public void onMetadataChanged(MediaMetadata metadata) { + } + + /** Stub method for ISessionControllerCallback.notifyQueueChanged */ + public void onQueueChanged(List<QueueItem> queue) { + } + + /** Stub method for ISessionControllerCallback.notifyQueueTitleChanged */ + public void onQueueTitleChanged(CharSequence title) { + } + + /** Stub method for ISessionControllerCallback.notifyExtrasChanged */ + public void onExtrasChanged(Bundle extras) { + } + + /** Stub method for ISessionControllerCallback.notifyVolumeInfoChanged */ + public void onVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType, + int maxVolume, int currentVolume) { + } + } + + private class CallbackStubProxy extends ISessionControllerCallback.Stub { + @Override + public void notifyEvent(String event, Bundle extras) { + mCallbackStub.onEvent(event, extras); + } + + @Override + public void notifySessionDestroyed() { + mCallbackStub.onSessionDestroyed(); + } + + @Override + public void notifyPlaybackStateChanged(PlaybackState state) { + mCallbackStub.onPlaybackStateChanged(state); + } + + @Override + public void notifyMetadataChanged(MediaMetadata metadata) { + mCallbackStub.onMetadataChanged(metadata); + } + + @Override + public void notifyQueueChanged(List<QueueItem> queue) { + mCallbackStub.onQueueChanged(queue); + } + + @Override + public void notifyQueueTitleChanged(CharSequence title) { + mCallbackStub.onQueueTitleChanged(title); + } + + @Override + public void notifyExtrasChanged(Bundle extras) { + mCallbackStub.onExtrasChanged(extras); + } + + @Override + public void notifyVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType, + int maxVolume, int currentVolume) { + mCallbackStub.onVolumeInfoChanged(volumeType, attrs, controlType, maxVolume, + currentVolume); + } + } +} diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl index bfc05fa4e3a4..5cf6dfee3b14 100644 --- a/media/java/android/media/session/ISession.aidl +++ b/media/java/android/media/session/ISession.aidl @@ -16,7 +16,6 @@ package android.media.session; import android.app.PendingIntent; -import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; import android.media.MediaMetadata; import android.media.session.ISessionController; @@ -41,7 +40,7 @@ interface ISession { // These commands are for the TransportPerformer void setMetadata(in MediaMetadata metadata, long duration, String metadataDescription); void setPlaybackState(in PlaybackState state); - void setQueue(in ParceledListSlice queue); + void setQueue(in List<MediaSession.QueueItem> queue); void setQueueTitle(CharSequence title); void setExtras(in Bundle extras); void setRatingType(int type); diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl index 626338d97ccb..9b86bfced340 100644 --- a/media/java/android/media/session/ISessionCallback.aidl +++ b/media/java/android/media/session/ISessionCallback.aidl @@ -17,7 +17,7 @@ package android.media.session; import android.content.Intent; import android.media.Rating; -import android.media.session.ISessionControllerCallback; +import android.media.session.ControllerCallbackLink; import android.net.Uri; import android.os.Bundle; import android.os.ResultReceiver; @@ -26,46 +26,46 @@ import android.os.ResultReceiver; * @hide */ oneway interface ISessionCallback { - void onCommand(String packageName, int pid, int uid, ISessionControllerCallback caller, + void notifyCommand(String packageName, int pid, int uid, in ControllerCallbackLink caller, String command, in Bundle args, in ResultReceiver cb); - void onMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent, + void notifyMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent, int sequenceNumber, in ResultReceiver cb); - void onMediaButtonFromController(String packageName, int pid, int uid, - ISessionControllerCallback caller, in Intent mediaButtonIntent); + void notifyMediaButtonFromController(String packageName, int pid, int uid, + in ControllerCallbackLink caller, in Intent mediaButtonIntent); // These callbacks are for the TransportPerformer - void onPrepare(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onPrepareFromMediaId(String packageName, int pid, int uid, - ISessionControllerCallback caller, String mediaId, in Bundle extras); - void onPrepareFromSearch(String packageName, int pid, int uid, - ISessionControllerCallback caller, String query, in Bundle extras); - void onPrepareFromUri(String packageName, int pid, int uid, ISessionControllerCallback caller, + void notifyPrepare(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void notifyPrepareFromMediaId(String packageName, int pid, int uid, + in ControllerCallbackLink caller, String mediaId, in Bundle extras); + void notifyPrepareFromSearch(String packageName, int pid, int uid, + in ControllerCallbackLink caller, String query, in Bundle extras); + void notifyPrepareFromUri(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, + in ControllerCallbackLink caller, String mediaId, in Bundle extras); + void notifyPlayFromSearch(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, in Uri uri, in Bundle extras); - void onPlay(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onPlayFromMediaId(String packageName, int pid, int uid, ISessionControllerCallback caller, - String mediaId, in Bundle extras); - void onPlayFromSearch(String packageName, int pid, int uid, ISessionControllerCallback caller, - String query, in Bundle extras); - void onPlayFromUri(String packageName, int pid, int uid, ISessionControllerCallback caller, - in Uri uri, in Bundle extras); - void onSkipToTrack(String packageName, int pid, int uid, ISessionControllerCallback caller, + void notifySkipToTrack(String packageName, int pid, int uid, in ControllerCallbackLink caller, long id); - void onPause(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onStop(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onNext(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onPrevious(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onFastForward(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onRewind(String packageName, int pid, int uid, ISessionControllerCallback caller); - void onSeekTo(String packageName, int pid, int uid, ISessionControllerCallback caller, + 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, long pos); - void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller, + void notifyRate(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Rating rating); - void onCustomAction(String packageName, int pid, int uid, ISessionControllerCallback caller, + void notifyCustomAction(String packageName, int pid, int uid, in ControllerCallbackLink caller, String action, in Bundle args); // These callbacks are for volume handling - void onAdjustVolume(String packageName, int pid, int uid, ISessionControllerCallback caller, + void notifyAdjustVolume(String packageName, int pid, int uid, in ControllerCallbackLink caller, int direction); - void onSetVolumeTo(String packageName, int pid, int uid, - ISessionControllerCallback caller, int value); + void notifySetVolumeTo(String packageName, int pid, int uid, + in ControllerCallbackLink caller, int value); } diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl index 861a8cea7db2..5c1915b724de 100644 --- a/media/java/android/media/session/ISessionController.aidl +++ b/media/java/android/media/session/ISessionController.aidl @@ -17,10 +17,9 @@ package android.media.session; import android.app.PendingIntent; import android.content.Intent; -import android.content.pm.ParceledListSlice; import android.media.MediaMetadata; import android.media.Rating; -import android.media.session.ISessionControllerCallback; +import android.media.session.ControllerCallbackLink; import android.media.session.MediaSession; import android.media.session.ParcelableVolumeInfo; import android.media.session.PlaybackState; @@ -36,52 +35,52 @@ import java.util.List; * @hide */ interface ISessionController { - void sendCommand(String packageName, ISessionControllerCallback caller, + void sendCommand(String packageName, in ControllerCallbackLink caller, String command, in Bundle args, in ResultReceiver cb); - boolean sendMediaButton(String packageName, ISessionControllerCallback caller, + boolean sendMediaButton(String packageName, in ControllerCallbackLink caller, boolean asSystemService, in KeyEvent mediaButton); - void registerCallbackListener(String packageName, ISessionControllerCallback cb); - void unregisterCallbackListener(ISessionControllerCallback cb); + void registerCallbackListener(String packageName, in ControllerCallbackLink cb); + void unregisterCallbackListener(in ControllerCallbackLink cb); boolean isTransportControlEnabled(); String getPackageName(); String getTag(); PendingIntent getLaunchPendingIntent(); long getFlags(); ParcelableVolumeInfo getVolumeAttributes(); - void adjustVolume(String packageName, ISessionControllerCallback caller, + void adjustVolume(String packageName, in ControllerCallbackLink caller, boolean asSystemService, int direction, int flags); - void setVolumeTo(String packageName, ISessionControllerCallback caller, + void setVolumeTo(String packageName, in ControllerCallbackLink caller, int value, int flags); // These commands are for the TransportControls - void prepare(String packageName, ISessionControllerCallback caller); - void prepareFromMediaId(String packageName, ISessionControllerCallback caller, + void prepare(String packageName, in ControllerCallbackLink caller); + void prepareFromMediaId(String packageName, in ControllerCallbackLink caller, String mediaId, in Bundle extras); - void prepareFromSearch(String packageName, ISessionControllerCallback caller, + void prepareFromSearch(String packageName, in ControllerCallbackLink caller, String string, in Bundle extras); - void prepareFromUri(String packageName, ISessionControllerCallback caller, + void prepareFromUri(String packageName, in ControllerCallbackLink caller, in Uri uri, in Bundle extras); - void play(String packageName, ISessionControllerCallback caller); - void playFromMediaId(String packageName, ISessionControllerCallback caller, + void play(String packageName, in ControllerCallbackLink caller); + void playFromMediaId(String packageName, in ControllerCallbackLink caller, String mediaId, in Bundle extras); - void playFromSearch(String packageName, ISessionControllerCallback caller, + void playFromSearch(String packageName, in ControllerCallbackLink caller, String string, in Bundle extras); - void playFromUri(String packageName, ISessionControllerCallback caller, + void playFromUri(String packageName, in ControllerCallbackLink caller, in Uri uri, in Bundle extras); - void skipToQueueItem(String packageName, ISessionControllerCallback caller, long id); - void pause(String packageName, ISessionControllerCallback caller); - void stop(String packageName, ISessionControllerCallback caller); - void next(String packageName, ISessionControllerCallback caller); - void previous(String packageName, ISessionControllerCallback caller); - void fastForward(String packageName, ISessionControllerCallback caller); - void rewind(String packageName, ISessionControllerCallback caller); - void seekTo(String packageName, ISessionControllerCallback caller, long pos); - void rate(String packageName, ISessionControllerCallback caller, in Rating rating); - void sendCustomAction(String packageName, ISessionControllerCallback caller, + void skipToQueueItem(String packageName, in ControllerCallbackLink caller, long id); + void pause(String packageName, in ControllerCallbackLink caller); + void stop(String packageName, in ControllerCallbackLink caller); + void next(String packageName, in ControllerCallbackLink caller); + void previous(String packageName, in ControllerCallbackLink caller); + void fastForward(String packageName, in ControllerCallbackLink caller); + void rewind(String packageName, in ControllerCallbackLink caller); + void seekTo(String packageName, in ControllerCallbackLink caller, long pos); + void rate(String packageName, in ControllerCallbackLink caller, in Rating rating); + void sendCustomAction(String packageName, in ControllerCallbackLink caller, String action, in Bundle args); MediaMetadata getMetadata(); PlaybackState getPlaybackState(); - ParceledListSlice getQueue(); + List<MediaSession.QueueItem> getQueue(); CharSequence getQueueTitle(); Bundle getExtras(); int getRatingType(); diff --git a/media/java/android/media/session/ISessionControllerCallback.aidl b/media/java/android/media/session/ISessionControllerCallback.aidl index cf3176706d7e..2f86c6c8df90 100644 --- a/media/java/android/media/session/ISessionControllerCallback.aidl +++ b/media/java/android/media/session/ISessionControllerCallback.aidl @@ -15,25 +15,26 @@ package android.media.session; -import android.content.pm.ParceledListSlice; +import android.media.AudioAttributes; import android.media.MediaMetadata; +import android.media.session.MediaSession; import android.media.session.ParcelableVolumeInfo; import android.media.session.PlaybackState; -import android.media.session.MediaSession; import android.os.Bundle; /** * @hide */ oneway interface ISessionControllerCallback { - void onEvent(String event, in Bundle extras); - void onSessionDestroyed(); + void notifyEvent(String event, in Bundle extras); + void notifySessionDestroyed(); // These callbacks are for the TransportController - void onPlaybackStateChanged(in PlaybackState state); - void onMetadataChanged(in MediaMetadata metadata); - void onQueueChanged(in ParceledListSlice queue); - void onQueueTitleChanged(CharSequence title); - void onExtrasChanged(in Bundle extras); - void onVolumeInfoChanged(in ParcelableVolumeInfo info); + void notifyPlaybackStateChanged(in PlaybackState state); + void notifyMetadataChanged(in MediaMetadata metadata); + void notifyQueueChanged(in List<MediaSession.QueueItem> queue); + void notifyQueueTitleChanged(CharSequence title); + void notifyExtrasChanged(in Bundle extras); + void notifyVolumeInfoChanged(int volumeType, in AudioAttributes attrs, int controlType, + int maxVolume, int currentVolume); } diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index 4ced7bee2cbd..580196736aba 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -22,7 +22,7 @@ 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.SessionCallbackLink; import android.os.Bundle; import android.view.KeyEvent; @@ -31,7 +31,7 @@ import android.view.KeyEvent; * @hide */ interface ISessionManager { - ISession createSession(String packageName, in ISessionCallback cb, String tag, int userId); + ISession createSession(String packageName, in SessionCallbackLink cb, String tag, int userId); List<IBinder> getSessions(in ComponentName compName, int userId); void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent, boolean needWakeLock); diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index b457357600fe..5eb77f9b58e2 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -21,12 +21,12 @@ import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; import android.content.Context; -import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.MediaMetadata; import android.media.Rating; import android.media.VolumeProvider; +import android.media.session.MediaSession.QueueItem; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -70,7 +70,8 @@ public final class MediaController { private final MediaSession.Token mToken; private final Context mContext; - private final CallbackStub mCbStub = new CallbackStub(this); + private final ControllerCallbackLink mCbStub = + new ControllerCallbackLink(new CallbackStub(this)); private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>(); private final Object mLock = new Object(); @@ -242,10 +243,7 @@ public final class MediaController { */ public @Nullable List<MediaSession.QueueItem> getQueue() { try { - ParceledListSlice queue = mSessionBinder.getQueue(); - if (queue != null) { - return queue.getList(); - } + return mSessionBinder.getQueue(); } catch (RemoteException e) { Log.wtf(TAG, "Error calling getQueue.", e); } @@ -1058,10 +1056,10 @@ public final class MediaController { } } - private final static class CallbackStub extends ISessionControllerCallback.Stub { + private static final class CallbackStub extends ControllerCallbackLink.CallbackStub { private final WeakReference<MediaController> mController; - public CallbackStub(MediaController controller) { + CallbackStub(MediaController controller) { mController = new WeakReference<MediaController>(controller); } @@ -1098,9 +1096,7 @@ public final class MediaController { } @Override - public void onQueueChanged(ParceledListSlice parceledQueue) { - List<MediaSession.QueueItem> queue = parceledQueue == null ? null : parceledQueue - .getList(); + public void onQueueChanged(List<QueueItem> queue) { MediaController controller = mController.get(); if (controller != null) { controller.postMessage(MSG_UPDATE_QUEUE, queue, null); @@ -1124,15 +1120,15 @@ public final class MediaController { } @Override - public void onVolumeInfoChanged(ParcelableVolumeInfo pvi) { + public void onVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType, + int maxVolume, int currentVolume) { MediaController controller = mController.get(); if (controller != null) { - PlaybackInfo info = new PlaybackInfo(pvi.volumeType, pvi.audioAttrs, - pvi.controlType, pvi.maxVolume, pvi.currentVolume); + PlaybackInfo info = new PlaybackInfo(volumeType, attrs, controlType, maxVolume, + currentVolume); controller.postMessage(MSG_UPDATE_VOLUME, info, null); } } - } private final static class MessageHandler extends Handler { diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 8962bb7fb4c4..0332f4cbba06 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -24,7 +24,6 @@ import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; import android.media.MediaDescription; import android.media.MediaMetadata; @@ -130,7 +129,7 @@ public final class MediaSession { private final MediaSession.Token mSessionToken; private final MediaController mController; private final ISession mBinder; - private final CallbackStub mCbStub; + private final SessionCallbackLink mCbStub; // Do not change the name of mCallback. Support lib accesses this by using reflection. @UnsupportedAppUsage @@ -173,7 +172,7 @@ public final class MediaSession { } mMaxBitmapSize = context.getResources().getDimensionPixelSize( com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize); - mCbStub = new CallbackStub(this); + mCbStub = new SessionCallbackLink(new CallbackStub(this)); MediaSessionManager manager = (MediaSessionManager) context .getSystemService(Context.MEDIA_SESSION_SERVICE); try { @@ -467,7 +466,7 @@ public final class MediaSession { */ public void setQueue(@Nullable List<QueueItem> queue) { try { - mBinder.setQueue(queue == null ? null : new ParceledListSlice<QueueItem>(queue)); + mBinder.setQueue(queue); } catch (RemoteException e) { Log.wtf("Dead object in setQueue.", e); } @@ -1063,7 +1062,7 @@ public final class MediaSession { /** * @hide */ - public static class CallbackStub extends ISessionCallback.Stub { + public static final class CallbackStub extends SessionCallbackLink.CallbackStub { private WeakReference<MediaSession> mMediaSession; public CallbackStub(MediaSession session) { @@ -1071,14 +1070,14 @@ public final class MediaSession { } private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { return new RemoteUserInfo(packageName, pid, uid, - caller != null ? caller.asBinder() : null); + caller != null ? caller.getBinder() : null); } @Override public void onCommand(String packageName, int pid, int uid, - ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) { + ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid, caller), @@ -1104,7 +1103,7 @@ public final class MediaSession { @Override public void onMediaButtonFromController(String packageName, int pid, int uid, - ISessionControllerCallback caller, Intent mediaButtonIntent) { + ControllerCallbackLink caller, Intent mediaButtonIntent) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid, caller), @@ -1114,7 +1113,7 @@ public final class MediaSession { @Override public void onPrepare(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1123,7 +1122,7 @@ public final class MediaSession { @Override public void onPrepareFromMediaId(String packageName, int pid, int uid, - ISessionControllerCallback caller, String mediaId, + ControllerCallbackLink caller, String mediaId, Bundle extras) { MediaSession session = mMediaSession.get(); if (session != null) { @@ -1134,7 +1133,7 @@ public final class MediaSession { @Override public void onPrepareFromSearch(String packageName, int pid, int uid, - ISessionControllerCallback caller, String query, + ControllerCallbackLink caller, String query, Bundle extras) { MediaSession session = mMediaSession.get(); if (session != null) { @@ -1145,7 +1144,7 @@ public final class MediaSession { @Override public void onPrepareFromUri(String packageName, int pid, int uid, - ISessionControllerCallback caller, Uri uri, Bundle extras) { + ControllerCallbackLink caller, Uri uri, Bundle extras) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid, caller), @@ -1155,7 +1154,7 @@ public final class MediaSession { @Override public void onPlay(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1164,7 +1163,7 @@ public final class MediaSession { @Override public void onPlayFromMediaId(String packageName, int pid, int uid, - ISessionControllerCallback caller, String mediaId, + ControllerCallbackLink caller, String mediaId, Bundle extras) { MediaSession session = mMediaSession.get(); if (session != null) { @@ -1175,7 +1174,7 @@ public final class MediaSession { @Override public void onPlayFromSearch(String packageName, int pid, int uid, - ISessionControllerCallback caller, String query, + ControllerCallbackLink caller, String query, Bundle extras) { MediaSession session = mMediaSession.get(); if (session != null) { @@ -1186,7 +1185,7 @@ public final class MediaSession { @Override public void onPlayFromUri(String packageName, int pid, int uid, - ISessionControllerCallback caller, Uri uri, Bundle extras) { + ControllerCallbackLink caller, Uri uri, Bundle extras) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid, caller), @@ -1196,7 +1195,7 @@ public final class MediaSession { @Override public void onSkipToTrack(String packageName, int pid, int uid, - ISessionControllerCallback caller, long id) { + ControllerCallbackLink caller, long id) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid, caller), id); @@ -1205,7 +1204,7 @@ public final class MediaSession { @Override public void onPause(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPause(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1214,7 +1213,7 @@ public final class MediaSession { @Override public void onStop(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchStop(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1223,7 +1222,7 @@ public final class MediaSession { @Override public void onNext(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchNext(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1232,7 +1231,7 @@ public final class MediaSession { @Override public void onPrevious(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1241,7 +1240,7 @@ public final class MediaSession { @Override public void onFastForward(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1250,7 +1249,7 @@ public final class MediaSession { @Override public void onRewind(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid, caller)); @@ -1259,7 +1258,7 @@ public final class MediaSession { @Override public void onSeekTo(String packageName, int pid, int uid, - ISessionControllerCallback caller, long pos) { + ControllerCallbackLink caller, long pos) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid, caller), pos); @@ -1267,7 +1266,7 @@ public final class MediaSession { } @Override - public void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller, + public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller, Rating rating) { MediaSession session = mMediaSession.get(); if (session != null) { @@ -1277,7 +1276,7 @@ public final class MediaSession { @Override public void onCustomAction(String packageName, int pid, int uid, - ISessionControllerCallback caller, String action, Bundle args) { + ControllerCallbackLink caller, String action, Bundle args) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid, caller), @@ -1287,7 +1286,7 @@ public final class MediaSession { @Override public void onAdjustVolume(String packageName, int pid, int uid, - ISessionControllerCallback caller, int direction) { + ControllerCallbackLink caller, int direction) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid, caller), @@ -1297,7 +1296,7 @@ public final class MediaSession { @Override public void onSetVolumeTo(String packageName, int pid, int uid, - ISessionControllerCallback caller, int value) { + ControllerCallbackLink caller, int value) { MediaSession session = mMediaSession.get(); if (session != null) { session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid, caller), diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 6a06dd07d22f..73dd55c1b88a 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -96,7 +96,7 @@ public final class MediaSessionManager { * @return The binder object from the system * @hide */ - public @NonNull ISession createSession(@NonNull MediaSession.CallbackStub cbStub, + public @NonNull ISession createSession(@NonNull SessionCallbackLink cbStub, @NonNull String tag, int userId) throws RemoteException { return mService.createSession(mContext.getPackageName(), cbStub, tag, userId); } diff --git a/media/java/android/media/session/SessionCallbackLink.aidl b/media/java/android/media/session/SessionCallbackLink.aidl new file mode 100644 index 000000000000..9c0ae055cb0c --- /dev/null +++ b/media/java/android/media/session/SessionCallbackLink.aidl @@ -0,0 +1,18 @@ +/* + * 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.session; + +parcelable SessionCallbackLink; diff --git a/media/java/android/media/session/SessionCallbackLink.java b/media/java/android/media/session/SessionCallbackLink.java new file mode 100644 index 000000000000..b13afb5908fc --- /dev/null +++ b/media/java/android/media/session/SessionCallbackLink.java @@ -0,0 +1,572 @@ +/* + * 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.session; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.content.Intent; +import android.media.Rating; +import android.net.Uri; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.RemoteException; +import android.os.ResultReceiver; + +/** + * Handles incoming commands to {@link MediaSession.Callback}. + * @hide + */ +@SystemApi +public final class SessionCallbackLink implements Parcelable { + CallbackStub mCallbackStub; + ISessionCallback mISessionCallback; + + /** + * Creator for stub (Callee) + */ + public SessionCallbackLink(@NonNull CallbackStub callbackStub) { + mCallbackStub = callbackStub; + mISessionCallback = new CallbackStubProxy(); + } + + /** + * Creator for interface (Caller) + */ + SessionCallbackLink(Parcel in) { + mCallbackStub = null; + mISessionCallback = ISessionCallback.Stub.asInterface(in.readStrongBinder()); + } + + /** Interface method for ISessionCallback.notifyCommand */ + public void notifyCommand(String packageName, int pid, int uid, + ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { + try { + mISessionCallback.notifyCommand(packageName, pid, uid, caller, command, args, cb); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyMediaButton */ + public void notifyMediaButton(String packageName, int pid, int uid, + Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb) { + try { + mISessionCallback.notifyMediaButton(packageName, pid, uid, mediaButtonIntent, + sequenceNumber, cb); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyMediaButtonFromController */ + public void notifyMediaButtonFromController(String packageName, int pid, int uid, + ControllerCallbackLink caller, Intent mediaButtonIntent) { + try { + mISessionCallback.notifyMediaButtonFromController(packageName, pid, uid, caller, + mediaButtonIntent); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPrepare */ + public void notifyPrepare(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyPrepare(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPrepareFromMediaId */ + public void notifyPrepareFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, Bundle extras) { + try { + mISessionCallback.notifyPrepareFromMediaId(packageName, pid, uid, caller, mediaId, + extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPrepareFromSearch */ + public void notifyPrepareFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, Bundle extras) { + try { + mISessionCallback.notifyPrepareFromSearch(packageName, pid, uid, caller, query, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPrepareFromUri */ + public void notifyPrepareFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + try { + mISessionCallback.notifyPrepareFromUri(packageName, pid, uid, caller, uri, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPlay */ + public void notifyPlay(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyPlay(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPlayFromMediaId */ + public void notifyPlayFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, Bundle extras) { + try { + mISessionCallback.notifyPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPlayFromSearch */ + public void notifyPlayFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, Bundle extras) { + try { + mISessionCallback.notifyPlayFromSearch(packageName, pid, uid, caller, query, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPlayFromUri */ + public void notifyPlayFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + try { + mISessionCallback.notifyPlayFromUri(packageName, pid, uid, caller, uri, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifySkipToTrack */ + public void notifySkipToTrack(String packageName, int pid, int uid, + ControllerCallbackLink caller, long id) { + try { + mISessionCallback.notifySkipToTrack(packageName, pid, uid, caller, id); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPause */ + public void notifyPause(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyPause(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyStop */ + public void notifyStop(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyStop(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyNext */ + public void notifyNext(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyNext(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyPrevious */ + public void notifyPrevious(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyPrevious(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyFastForward */ + public void notifyFastForward(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyFastForward(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyRewind */ + public void notifyRewind(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + try { + mISessionCallback.notifyRewind(packageName, pid, uid, caller); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifySeekTo */ + public void notifySeekTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, long pos) { + try { + mISessionCallback.notifySeekTo(packageName, pid, uid, caller, pos); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyRate */ + public void notifyRate(String packageName, int pid, int uid, ControllerCallbackLink caller, + Rating rating) { + try { + mISessionCallback.notifyRate(packageName, pid, uid, caller, rating); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyCustomAction */ + public void notifyCustomAction(String packageName, int pid, int uid, + ControllerCallbackLink caller, String action, Bundle args) { + try { + mISessionCallback.notifyCustomAction(packageName, pid, uid, caller, action, args); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifyAdjustVolume */ + public void notifyAdjustVolume(String packageName, int pid, int uid, + ControllerCallbackLink caller, int direction) { + try { + mISessionCallback.notifyAdjustVolume(packageName, pid, uid, caller, direction); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Interface method for ISessionCallback.notifySetVolumeTo */ + public void notifySetVolumeTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, int value) { + try { + mISessionCallback.notifySetVolumeTo(packageName, pid, uid, caller, value); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** Gets the binder */ + 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 Parcelable.Creator<SessionCallbackLink> CREATOR = + new Parcelable.Creator<SessionCallbackLink>() { + @Override + public SessionCallbackLink createFromParcel(Parcel in) { + return new SessionCallbackLink(in); + } + + @Override + public SessionCallbackLink[] newArray(int size) { + return new SessionCallbackLink[size]; + } + }; + + /** + * Class for Stub implementation + */ + public abstract static class CallbackStub { + /** Stub method for ISessionCallback.notifyCommand */ + public void onCommand(String packageName, int pid, int uid, ControllerCallbackLink caller, + String command, Bundle args, ResultReceiver cb) { + } + + /** Stub method for ISessionCallback.notifyMediaButton */ + public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent, + int sequenceNumber, ResultReceiver cb) { + } + + /** Stub method for ISessionCallback.notifyMediaButtonFromController */ + public void onMediaButtonFromController(String packageName, int pid, int uid, + ControllerCallbackLink caller, Intent mediaButtonIntent) { + } + + /** Stub method for ISessionCallback.notifyPrepare */ + public void onPrepare(String packageName, int pid, int uid, ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifyPrepareFromMediaId */ + public void onPrepareFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, Bundle extras) { + } + + /** Stub method for ISessionCallback.notifyPrepareFromSearch */ + public void onPrepareFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, Bundle extras) { + } + + /** Stub method for ISessionCallback.notifyPrepareFromUri */ + public void onPrepareFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + } + + /** Stub method for ISessionCallback.notifyPlay */ + public void onPlay(String packageName, int pid, int uid, ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifyPlayFromMediaId */ + public void onPlayFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, Bundle extras) { + } + + /** Stub method for ISessionCallback.notifyPlayFromSearch */ + public void onPlayFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, Bundle extras) { + } + + /** Stub method for ISessionCallback.notifyPlayFromUri */ + public void onPlayFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + } + + /** Stub method for ISessionCallback.notifySkipToTrack */ + public void onSkipToTrack(String packageName, int pid, int uid, + ControllerCallbackLink caller, long id) { + } + + /** Stub method for ISessionCallback.notifyPause */ + public void onPause(String packageName, int pid, int uid, ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifyStop */ + public void onStop(String packageName, int pid, int uid, ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifyNext */ + public void onNext(String packageName, int pid, int uid, ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifyPrevious */ + public void onPrevious(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifyFastForward */ + public void onFastForward(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifyRewind */ + public void onRewind(String packageName, int pid, int uid, ControllerCallbackLink caller) { + } + + /** Stub method for ISessionCallback.notifySeekTo */ + public void onSeekTo(String packageName, int pid, int uid, ControllerCallbackLink caller, + long pos) { + } + + /** Stub method for ISessionCallback.notifyRate */ + public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller, + Rating rating) { + } + + /** Stub method for ISessionCallback.notifyCustomAction */ + public void onCustomAction(String packageName, int pid, int uid, + ControllerCallbackLink caller, String action, Bundle args) { + } + + /** Stub method for ISessionCallback.notifyAdjustVolume */ + public void onAdjustVolume(String packageName, int pid, int uid, + ControllerCallbackLink caller, int direction) { + } + + /** Stub method for ISessionCallback.notifySetVolumeTo */ + public void onSetVolumeTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, int value) { + } + } + + private class CallbackStubProxy extends ISessionCallback.Stub { + @Override + public void notifyCommand(String packageName, int pid, int uid, + ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { + mCallbackStub.onCommand(packageName, pid, uid, caller, command, args, cb); + } + + @Override + public void notifyMediaButton(String packageName, int pid, int uid, + Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb) { + mCallbackStub.onMediaButton(packageName, pid, uid, mediaButtonIntent, sequenceNumber, + cb); + } + + @Override + public void notifyMediaButtonFromController(String packageName, int pid, int uid, + ControllerCallbackLink caller, Intent mediaButtonIntent) { + mCallbackStub.onMediaButtonFromController(packageName, pid, uid, caller, + mediaButtonIntent); + } + + @Override + public void notifyPrepare(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onPrepare(packageName, pid, uid, caller); + } + + @Override + public void notifyPrepareFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, Bundle extras) { + mCallbackStub.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras); + } + + @Override + public void notifyPrepareFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, Bundle extras) { + mCallbackStub.onPrepareFromSearch(packageName, pid, uid, caller, query, extras); + } + + @Override + public void notifyPrepareFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + mCallbackStub.onPrepareFromUri(packageName, pid, uid, caller, uri, extras); + } + + @Override + public void notifyPlay(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onPlay(packageName, pid, uid, caller); + } + + @Override + public void notifyPlayFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, Bundle extras) { + mCallbackStub.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); + } + + @Override + public void notifyPlayFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, Bundle extras) { + mCallbackStub.onPlayFromSearch(packageName, pid, uid, caller, query, extras); + } + + @Override + public void notifyPlayFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + mCallbackStub.onPlayFromUri(packageName, pid, uid, caller, uri, extras); + } + + @Override + public void notifySkipToTrack(String packageName, int pid, int uid, + ControllerCallbackLink caller, long id) { + mCallbackStub.onSkipToTrack(packageName, pid, uid, caller, id); + } + + @Override + public void notifyPause(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onPause(packageName, pid, uid, caller); + } + + @Override + public void notifyStop(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onStop(packageName, pid, uid, caller); + } + + @Override + public void notifyNext(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onNext(packageName, pid, uid, caller); + } + + @Override + public void notifyPrevious(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onPrevious(packageName, pid, uid, caller); + } + + @Override + public void notifyFastForward(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onFastForward(packageName, pid, uid, caller); + } + + @Override + public void notifyRewind(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + mCallbackStub.onRewind(packageName, pid, uid, caller); + } + + @Override + public void notifySeekTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, long pos) { + mCallbackStub.onSeekTo(packageName, pid, uid, caller, pos); + } + + @Override + public void notifyRate(String packageName, int pid, int uid, ControllerCallbackLink caller, + Rating rating) { + mCallbackStub.onRate(packageName, pid, uid, caller, rating); + } + + @Override + public void notifyCustomAction(String packageName, int pid, int uid, + ControllerCallbackLink caller, String action, Bundle args) { + mCallbackStub.onCustomAction(packageName, pid, uid, caller, action, args); + } + + @Override + public void notifyAdjustVolume(String packageName, int pid, int uid, + ControllerCallbackLink caller, int direction) { + mCallbackStub.onAdjustVolume(packageName, pid, uid, caller, direction); + } + + @Override + public void notifySetVolumeTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, int value) { + mCallbackStub.onSetVolumeTo(packageName, pid, uid, caller, value); + } + } +} diff --git a/packages/BackupRestoreConfirmation/res/values-as/strings.xml b/packages/BackupRestoreConfirmation/res/values-as/strings.xml index 4a86d6477f51..76ec60b166a8 100644 --- a/packages/BackupRestoreConfirmation/res/values-as/strings.xml +++ b/packages/BackupRestoreConfirmation/res/values-as/strings.xml @@ -32,8 +32,8 @@ <string name="backup_enc_password_required" msgid="7889652203371654149">"যিহেতু আপোনাৰ ডিভাইচটো এনক্ৰিপ্ট কৰা হৈছে, আপুনি আপোনাৰ বেকআপ এনক্ৰিপ্ট কৰাৰ প্ৰয়োজন। অনুগ্ৰহ কৰি তলত এটা পাছৱৰ্ড দিয়ক:"</string> <string name="restore_enc_password_text" msgid="6140898525580710823">"যদি পুনঃস্থাপন কৰিবলগীয়া ডেটা এনক্ৰিপ্ট কৰা আছে, তেন্তে তলত পাছৱৰ্ড দিয়ক:"</string> <string name="toast_backup_started" msgid="550354281452756121">"বেকআপ লোৱা কাৰ্য আৰম্ভ কৰি আছে..."</string> - <string name="toast_backup_ended" msgid="3818080769548726424">"বেকআপ লোৱা সম্পূৰ্ণ হ\'ল"</string> + <string name="toast_backup_ended" msgid="3818080769548726424">"বেকআপ লোৱা সম্পূৰ্ণ হ’ল"</string> <string name="toast_restore_started" msgid="7881679218971277385">"পুনঃস্থাপন কাৰ্য আৰম্ভ কৰি আছে..."</string> - <string name="toast_restore_ended" msgid="1764041639199696132">"পুনঃস্থাপন কাৰ্য সমাপ্ত হ\'ল"</string> + <string name="toast_restore_ended" msgid="1764041639199696132">"পুনঃস্থাপন কাৰ্য সমাপ্ত হ’ল"</string> <string name="toast_timeout" msgid="5276598587087626877">"কাৰ্যটোৰ সময়সীমা উকলি গ\'ল"</string> </resources> diff --git a/packages/BackupRestoreConfirmation/res/values-ne/strings.xml b/packages/BackupRestoreConfirmation/res/values-ne/strings.xml index d01ad5075998..2296b9fb72a5 100644 --- a/packages/BackupRestoreConfirmation/res/values-ne/strings.xml +++ b/packages/BackupRestoreConfirmation/res/values-ne/strings.xml @@ -29,7 +29,7 @@ <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया तल तपाईंको उपकरण एन्क्रिप्सन पासवर्ड प्रविष्टि गर्नुहोस्: यो ब्याकप सँग्रह एन्क्रिप्ट गर्न पनि प्रयोग हुने छ।"</string> <string name="backup_enc_password_text" msgid="4981585714795233099">"ब्याकप डेटालाई encrypt गर्न पासवर्ड प्रविष्टि गर्नुहोस्, यदि यो खालि छोडिएको खण्डमा तपाईको पुरानै पासवर्ड प्रयोग हुने छ।"</string> <string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि तपाईं पूर्ण ब्याकअप डेटा इन्क्रिप्ट गर्न चाहनु हुन्छ भने तल पासवर्ड प्रविष्टि गर्नुहोस्।"</string> - <string name="backup_enc_password_required" msgid="7889652203371654149">"तपाईँको उपकरण गुप्तिकरण गरिए देखि, तपाईंले आफ्नो जगेडा गुप्तिकरण गर्न आवश्यक छ। कृपया तल पासवर्ड प्रविष्ट गर्नुहोस्:"</string> + <string name="backup_enc_password_required" msgid="7889652203371654149">"तपाईँको उपकरण गुप्तिकरण गरिए देखि, तपाईंले आफ्नो जगेडा गुप्तिकरण गर्न आवश्यक छ। कृपया तल पासवर्ड प्रविष्टि गर्नुहोस्:"</string> <string name="restore_enc_password_text" msgid="6140898525580710823">"यदि पुनःबहाली डेटा इन्क्रिप्ट छ भने कृपया तल पासवर्ड प्रविष्टि गर्नुहोस्:"</string> <string name="toast_backup_started" msgid="550354281452756121">"जगेडा राख्न सुरु हुँदै..."</string> <string name="toast_backup_ended" msgid="3818080769548726424">"ब्याकअप सकियो"</string> diff --git a/packages/CaptivePortalLogin/res/values-gl/strings.xml b/packages/CaptivePortalLogin/res/values-gl/strings.xml index 64195168f76f..f6f4aea0c639 100644 --- a/packages/CaptivePortalLogin/res/values-gl/strings.xml +++ b/packages/CaptivePortalLogin/res/values-gl/strings.xml @@ -13,7 +13,7 @@ <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do sitio non coincide co nome que aparece no certificado."</string> <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado caducou."</string> <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aínda non é válido."</string> - <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado ten unha data non válida."</string> + <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado ten unha data non-válida."</string> <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado non é válido."</string> <string name="ssl_error_unknown" msgid="4405203446079465859">"Produciuse un erro descoñecido relacionado co certificado."</string> <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguranza"</string> diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml index 1dca10a04c43..2fe740d51e8f 100644 --- a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml @@ -76,7 +76,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@null" - systemui:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivity;launchFlags=0x14008000;end" + systemui:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivity;launchFlags=0x24000000;end" /> <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" diff --git a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java index d5dd3c3eaca0..4ef926fae816 100644 --- a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java +++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java @@ -28,7 +28,7 @@ import androidx.annotation.IdRes; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.R; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher; /** * A view that forms the header of the notification panel. This view will ensure that any diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java index 5bf30ca10694..b36a7da35acf 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java @@ -45,9 +45,7 @@ public class AssitantButton extends CarFacetButton { Log.d(TAG, "IVoiceInteractionSessionShowCallback onShown()"); } }; - - private static final String EXTRA_CAR_PUSH_TO_TALK = - "com.android.car.input.EXTRA_CAR_PUSH_TO_TALK"; + private final AssistUtils mAssistUtils; public AssitantButton(Context context, AttributeSet attrs) { @@ -60,7 +58,6 @@ public class AssitantButton extends CarFacetButton { private void showAssistant() { final Bundle args = new Bundle(); - args.putBoolean(EXTRA_CAR_PUSH_TO_TALK, true); mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_ASSIST_GESTURE, mShowCallback, /*activityToken=*/ null); } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index 7028999c159c..dbddf71d342c 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -280,7 +280,9 @@ public class CarStatusBar extends StatusBar implements buildNavBarContent(); attachNavBarWindows(); - mNavigationBarController.createNavigationBars(); + // There has been a car customized nav bar on the default display, so just create nav bars + // on external displays. + mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */); } private void buildNavBarContent() { @@ -447,12 +449,6 @@ public class CarStatusBar extends StatusBar implements } } - - @Override - public View getNavigationBarWindow() { - return mNavigationBarWindow; - } - @Override protected View.OnTouchListener getStatusBarWindowTouchListener() { // Usually, a touch on the background window will dismiss the notification shade. However, diff --git a/packages/CarrierDefaultApp/res/values-as/strings.xml b/packages/CarrierDefaultApp/res/values-as/strings.xml index 8650171ee7f0..4b36b06e35c7 100644 --- a/packages/CarrierDefaultApp/res/values-as/strings.xml +++ b/packages/CarrierDefaultApp/res/values-as/strings.xml @@ -2,16 +2,16 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string> - <string name="android_system_label" msgid="2797790869522345065">"ম\'বাইল সেৱা প্ৰদান কৰা কোম্পানী"</string> - <string name="portal_notification_id" msgid="5155057562457079297">"ম\'বাইল ডেটা শেষ হৈছে"</string> - <string name="no_data_notification_id" msgid="668400731803969521">"আপোনাৰ ম\'বাইল ডেটা সেৱা নিষ্ক্ৰিয় কৰা হৈছে"</string> + <string name="android_system_label" msgid="2797790869522345065">"ম’বাইল সেৱা প্ৰদান কৰা কোম্পানী"</string> + <string name="portal_notification_id" msgid="5155057562457079297">"ম’বাইল ডেটা শেষ হৈছে"</string> + <string name="no_data_notification_id" msgid="668400731803969521">"আপোনাৰ ম’বাইল ডেটা সেৱা নিষ্ক্ৰিয় কৰা হৈছে"</string> <string name="portal_notification_detail" msgid="2295729385924660881">"%s ৱেবছাইটটোলৈ যাবলৈ টিপক"</string> <string name="no_data_notification_detail" msgid="3112125343857014825">"অনুগ্ৰহ কৰি আপোনাৰ সেৱা প্ৰদানকাৰী %sৰ সৈতে যোগাযোগ কৰক"</string> - <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"কোনো ম\'বাইল ডেটা সংযোগ নাই"</string> + <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"কোনো ম’বাইল ডেটা সংযোগ নাই"</string> <string name="no_mobile_data_connection" msgid="544980465184147010">"%sৰ যোগেৰে ডেটা বা ৰ\'মিঙৰ আঁচনি যোগ কৰক"</string> - <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ম\'বাইল ডেটাৰ স্থিতি"</string> - <string name="action_bar_label" msgid="4290345990334377177">"ম\'বাইল নেটৱৰ্কত ছাইন ইন কৰক"</string> + <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ম’বাইল ডেটাৰ স্থিতি"</string> + <string name="action_bar_label" msgid="4290345990334377177">"ম’বাইল নেটৱৰ্কত ছাইন ইন কৰক"</string> <string name="ssl_error_warning" msgid="3127935140338254180">"আপুনি সংযোগ কৰিবলৈ বিচৰা নেটৱৰ্কটোত সুৰক্ষাজনিত সমস্যা আছে।"</string> - <string name="ssl_error_example" msgid="6188711843183058764">"উদাহৰণ স্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string> + <string name="ssl_error_example" msgid="6188711843183058764">"উদাহৰণস্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string> <string name="ssl_error_continue" msgid="1138548463994095584">"তথাপিও ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string> </resources> diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp new file mode 100644 index 000000000000..55bb5175c28d --- /dev/null +++ b/packages/NetworkStack/Android.bp @@ -0,0 +1,37 @@ +// +// 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. +// + +// Library including the network stack, used to compile the network stack app, or linked into the +// system server on devices that run the stack there +java_library { + name: "NetworkStackLib", + installable: true, + srcs: [ + "src/**/*.java", + ], +} + +// Updatable network stack packaged as an application +android_app { + name: "NetworkStack", + platform_apis: true, + certificate: "platform", + privileged: true, + static_libs: [ + "NetworkStackLib" + ], + manifest: "AndroidManifest.xml", +}
\ No newline at end of file diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml new file mode 100644 index 000000000000..d1c5cb67197e --- /dev/null +++ b/packages/NetworkStack/AndroidManifest.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (C) 2014 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.google.android.networkstack" + android:sharedUserId="android.uid.networkstack"> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <!-- Launch captive portal app as specific user --> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> + <application + android:label="NetworkStack" + android:defaultToDeviceProtectedStorage="true" + android:directBootAware="true" + android:usesCleartextTraffic="true"> + <service android:name="com.android.server.NetworkStackService"> + <intent-filter> + <action android:name="android.net.INetworkStackConnector"/> + </intent-filter> + </service> + </application> +</manifest> diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java new file mode 100644 index 000000000000..5afaf586f74d --- /dev/null +++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java @@ -0,0 +1,74 @@ +/* + * 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.server; + +import static android.os.Binder.getCallingUid; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.Service; +import android.content.Intent; +import android.net.INetworkStackConnector; +import android.os.IBinder; +import android.os.Process; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * Android service used to start the network stack when bound to via an intent. + * + * <p>The service returns a binder for the system server to communicate with the network stack. + */ +public class NetworkStackService extends Service { + private static final String TAG = NetworkStackService.class.getSimpleName(); + + /** + * Create a binder connector for the system server to communicate with the network stack. + * + * <p>On platforms where the network stack runs in the system server process, this method may + * be called directly instead of obtaining the connector by binding to the service. + */ + public static IBinder makeConnector() { + return new NetworkStackConnector(); + } + + @NonNull + @Override + public IBinder onBind(Intent intent) { + return makeConnector(); + } + + private static class NetworkStackConnector extends INetworkStackConnector.Stub { + // TODO: makeDhcpServer(), etc. will go here. + + @Override + protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, + @Nullable String[] args) { + checkCaller(); + fout.println("NetworkStack logs:"); + // TODO: dump logs here + } + } + + private static void checkCaller() { + // TODO: check that the calling PID is the system server. + if (getCallingUid() != Process.SYSTEM_UID && getCallingUid() != Process.ROOT_UID) { + throw new SecurityException("Invalid caller: " + getCallingUid()); + } + } +} diff --git a/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java b/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java index 0312b81493be..28b05396acce 100644 --- a/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java +++ b/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java @@ -39,12 +39,14 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ProgressBar; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.android.hotspot2.R; import java.net.MalformedURLException; import java.net.URL; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + /** * Online Sign Up Login Web View launched during Provision Process of Hotspot 2.0 rel2. @@ -252,6 +254,10 @@ public class OsuLoginActivity extends Activity { @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + if (request.getUrl().toString().startsWith("http://127.0.0.1")) { + view.stopLoading(); + } + if (request.isForMainFrame()) { // This happens right after getting HTTP redirect response from an OSU server // since no more Http request is allowed to send to the OSU server. diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml index dfee4e83d7a3..ce007efd68d6 100644 --- a/packages/PackageInstaller/res/values-af/strings.xml +++ b/packages/PackageInstaller/res/values-af/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Wil jy hierdie program vir die gebruiker <xliff:g id="USERNAME">%1$s</xliff:g> deïnstalleer?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word. Dit beïnvloed alle gebruikers van hierdie toestel, insluitend dié met werkprofiele."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Verwyder ook <xliff:g id="SIZE">%1$s</xliff:g> se geassosieerde medialêers."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Hou <xliff:g id="SIZE">%1$s</xliff:g> se programdata."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Voer tans deïnstallerings uit"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislukte deïnstallerings"</string> <string name="uninstalling" msgid="8709566347688966845">"Deïnstalleer tans …"</string> diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml index cfdeb59d0b83..21cdaa6e8b5b 100644 --- a/packages/PackageInstaller/res/values-am/strings.xml +++ b/packages/PackageInstaller/res/values-am/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"በማራገፍ ላይ…"</string> diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml index da919830c761..edbd1782092c 100644 --- a/packages/PackageInstaller/res/values-ar/strings.xml +++ b/packages/PackageInstaller/res/values-ar/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"جارٍ إلغاء التثبيت…"</string> diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml index 2f2d8671d04b..d3429bf4ab2c 100644 --- a/packages/PackageInstaller/res/values-as/strings.xml +++ b/packages/PackageInstaller/res/values-as/strings.xml @@ -22,10 +22,10 @@ <string name="cancel" msgid="1018267193425558088">"বাতিল কৰক"</string> <string name="installing" msgid="4921993079741206516">"ইনষ্টল কৰি থকা হৈছে…"</string> <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ইনষ্টল কৰি থকা হৈছে…"</string> - <string name="install_done" msgid="5987363587661783896">"এপ্ ইনষ্টল কৰা হ\'ল।"</string> + <string name="install_done" msgid="5987363587661783896">"এপ্ ইনষ্টল কৰা হ’ল।"</string> <string name="install_confirm_question" msgid="8176284075816604590">"আপুনি এই এপ্লিকেশ্বনটো ইনষ্টল কৰিব বিচাৰেনে?"</string> - <string name="install_confirm_question_update" msgid="7942235418781274635">"আপুনি আগৰে পৰা থকা এপ্লিকেশ্বন আপডে\'ট কৰিব বিচাৰেনে? আপোনাৰ আগৰ ডেটা নেহেৰায়।"</string> - <string name="install_confirm_question_update_system" msgid="4713001702777910263">"আপুনি এই আগৰে পৰা থকা এপ্লিকেশ্বনটো আপডে\'ট কৰিব বিচাৰেনে? আপোনাৰ আগৰ ডেটা নেহেৰায়।"</string> + <string name="install_confirm_question_update" msgid="7942235418781274635">"আপুনি আগৰে পৰা থকা এপ্লিকেশ্বন আপডে’ট কৰিব বিচাৰেনে? আপোনাৰ আগৰ ডেটা নেহেৰায়।"</string> + <string name="install_confirm_question_update_system" msgid="4713001702777910263">"আপুনি এই আগৰে পৰা থকা এপ্লিকেশ্বনটো আপডে’ট কৰিব বিচাৰেনে? আপোনাৰ আগৰ ডেটা নেহেৰায়।"</string> <string name="install_failed" msgid="5777824004474125469">"এপ্ ইনষ্টল কৰা হোৱা নাই।"</string> <string name="install_failed_blocked" msgid="8512284352994752094">"পেকেজটোৰ ইনষ্টল অৱৰোধ কৰা হৈছে।"</string> <string name="install_failed_conflict" msgid="3493184212162521426">"এপটো ইনষ্টল কৰিব পৰা নগ\'ল কাৰণ ইয়াৰ সৈতে আগৰে পৰা থকা এটা পেকেজৰ সংঘাত হৈছে।"</string> @@ -51,19 +51,21 @@ <string name="generic_error_dlg_title" msgid="5863195085927067752">"আসোঁৱাহ"</string> <string name="generic_error_dlg_text" msgid="5287861443265795232">"এপ্ আনইনষ্টল কৰিব পৰা নগ\'ল।"</string> <string name="uninstall_application_title" msgid="4045420072401428123">"এপ্ আনইনষ্টল কৰক"</string> - <string name="uninstall_update_title" msgid="824411791011583031">"আপডে\'ট আনইনষ্টল কৰক"</string> + <string name="uninstall_update_title" msgid="824411791011583031">"আপডে’ট আনইনষ্টল কৰক"</string> <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> হৈছে তলৰ এপটোৰ এটা অংশ:"</string> <string name="uninstall_application_text" msgid="3816830743706143980">"আপুনি এই এপটো আনইনষ্টল কৰিব বিচাৰেনে?"</string> <string name="uninstall_application_text_all_users" msgid="575491774380227119">"আপুনি "<b>"সকলো"</b>" ব্যৱহাৰকাৰীৰ বাবে এই এপটো আনইনষ্টল কৰিব বিচাৰেনে? এপ্লিকেশ্বন আৰু ইয়াৰ ডেটা ডিভাইচটোত থকা "<b>"সকলো"</b>" ব্যৱহাৰকাৰীৰ পৰা আঁতৰোৱা হ\'ব৷"</string> <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> <string name="uninstalling" msgid="8709566347688966845">"আনইনষ্টল কৰি থকা হৈছে…"</string> <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰি থকা হৈছে…"</string> <string name="uninstall_done" msgid="439354138387969269">"আনইনষ্টল কৰা হ’ল।"</string> - <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰা হ\'ল"</string> + <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰা হ’ল"</string> <string name="uninstall_failed" msgid="1847750968168364332">"আনইনষ্টল কৰিব পৰা নগ\'ল।"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰিব পৰা নগ\'ল।"</string> <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"ডিভাইচৰ সক্ৰিয় প্ৰশাসক এপ্ আনইনষ্টল কৰিব নোৱাৰি"</string> diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml index 478322a1dfff..caa6f7d5cc1f 100644 --- a/packages/PackageInstaller/res/values-az/strings.xml +++ b/packages/PackageInstaller/res/values-az/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı istifadəçi üçün bu tətbiqi sistemdən silmək istəyirsiniz?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək. Bu, iş profilləri daxil olmaqla bu cihazın bütün istifadəçilərinə təsir edir."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Həmçinin, <xliff:g id="SIZE">%1$s</xliff:g> həcmində əlaqədar media fayllarını silin."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Tətbiq datasının <xliff:g id="SIZE">%1$s</xliff:g> hissəsini saxlayın."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"İşləyən sistemlər silinmələr"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Uğursuz olan sistemlər silinmələr"</string> <string name="uninstalling" msgid="8709566347688966845">"Sistemdən silinir..."</string> diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml index cab6be5d9902..689692def477 100644 --- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml +++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li da deinstalirate ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni. Ovo utiče na sve korisnike ovog uređaja, uključujući i one sa profilima za Work."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Ukloni i <xliff:g id="SIZE">%1$s</xliff:g> povezanih medijskih datoteka."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Zadrži <xliff:g id="SIZE">%1$s</xliff:g> podataka aplikacije."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Aktivna deinstaliranja"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspela deinstaliranja"</string> <string name="uninstalling" msgid="8709566347688966845">"Deinstalira se…"</string> diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml index 4433b73de0b0..a6e87e95117d 100644 --- a/packages/PackageInstaller/res/values-be/strings.xml +++ b/packages/PackageInstaller/res/values-be/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Ідзе выдаленне…"</string> diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml index 2b76bddce579..51a0e88446c2 100644 --- a/packages/PackageInstaller/res/values-bg/strings.xml +++ b/packages/PackageInstaller/res/values-bg/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Деинсталира се..."</string> diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml index ee264d91b944..2e610bb6f3e7 100644 --- a/packages/PackageInstaller/res/values-bn/strings.xml +++ b/packages/PackageInstaller/res/values-bn/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"আনইনস্টল করা হচ্ছে…"</string> diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml index 97ba693322e1..84a5a1671835 100644 --- a/packages/PackageInstaller/res/values-bs/strings.xml +++ b/packages/PackageInstaller/res/values-bs/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li deinstalirati ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni. To će uticati na sve korisnike uređaja, uključujući i one s radnim profilima."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Također ukloni <xliff:g id="SIZE">%1$s</xliff:g> povezanih medijskih fajlova."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Zadržati <xliff:g id="SIZE">%1$s</xliff:g> podataka aplikacije."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Tekuća deinstaliranja"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspjela deinstaliranja"</string> <string name="uninstalling" msgid="8709566347688966845">"Deinstaliranje..."</string> diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml index a0908081e3cf..6c081619f03c 100644 --- a/packages/PackageInstaller/res/values-ca/strings.xml +++ b/packages/PackageInstaller/res/values-ca/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"S\'està desinstal·lant…"</string> diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml index 1e46214b4b0c..8e4ce59cf3f1 100644 --- a/packages/PackageInstaller/res/values-cs/strings.xml +++ b/packages/PackageInstaller/res/values-cs/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Chcete tuto aplikaci pro uživatele <xliff:g id="USERNAME">%1$s</xliff:g> odinstalovat?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna. Tato akce ovlivní všechny uživatele zařízení, včetně uživatelů s pracovním profilem."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Odstranit také <xliff:g id="SIZE">%1$s</xliff:g> přidružených mediálních souborů."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Ponechat data aplikace o velikosti <xliff:g id="SIZE">%1$s</xliff:g>."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Probíhající odinstalace"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neúspěšné odinstalace"</string> <string name="uninstalling" msgid="8709566347688966845">"Odinstalace…"</string> diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml index d35fb9caa6f1..933ff3f70b31 100644 --- a/packages/PackageInstaller/res/values-da/strings.xml +++ b/packages/PackageInstaller/res/values-da/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Vil du afinstallere denne app for brugeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes. Dette påvirker alle brugere af denne enhed, bl.a. brugere med arbejdsprofiler."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Fjern også <xliff:g id="SIZE">%1$s</xliff:g> tilknyttede mediefiler."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Behold <xliff:g id="SIZE">%1$s</xliff:g> appdata."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Igangværende afinstallationer"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislykkede afinstallationer"</string> <string name="uninstalling" msgid="8709566347688966845">"Afinstallerer…"</string> diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml index 367eb243e1e9..4ad9b7387898 100644 --- a/packages/PackageInstaller/res/values-de/strings.xml +++ b/packages/PackageInstaller/res/values-de/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Wird deinstalliert..."</string> diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml index d179acb0dbb9..36f9f2d4b2f5 100644 --- a/packages/PackageInstaller/res/values-el/strings.xml +++ b/packages/PackageInstaller/res/values-el/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Απεγκατάσταση…"</string> diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml index 4016288a420d..51e61d02f6a7 100644 --- a/packages/PackageInstaller/res/values-en-rAU/strings.xml +++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"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> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Also remove <xliff:g id="SIZE">%1$s</xliff:g> of associated media files."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Keep <xliff:g id="SIZE">%1$s</xliff:g> of app data."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string> <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string> diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml index 4016288a420d..51e61d02f6a7 100644 --- a/packages/PackageInstaller/res/values-en-rCA/strings.xml +++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"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> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Also remove <xliff:g id="SIZE">%1$s</xliff:g> of associated media files."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Keep <xliff:g id="SIZE">%1$s</xliff:g> of app data."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string> <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string> diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml index 4016288a420d..51e61d02f6a7 100644 --- a/packages/PackageInstaller/res/values-en-rGB/strings.xml +++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"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> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Also remove <xliff:g id="SIZE">%1$s</xliff:g> of associated media files."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Keep <xliff:g id="SIZE">%1$s</xliff:g> of app data."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string> <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string> diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml index 4016288a420d..51e61d02f6a7 100644 --- a/packages/PackageInstaller/res/values-en-rIN/strings.xml +++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"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> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Also remove <xliff:g id="SIZE">%1$s</xliff:g> of associated media files."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Keep <xliff:g id="SIZE">%1$s</xliff:g> of app data."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string> <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string> diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml index 68332630acff..de4b31eb85ad 100644 --- a/packages/PackageInstaller/res/values-en-rXC/strings.xml +++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"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> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Also remove <xliff:g id="SIZE">%1$s</xliff:g> of associated media files."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Keep <xliff:g id="SIZE">%1$s</xliff:g> of app data."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstalls"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstalls"</string> <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string> diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml index dd45a791040c..ce8edfee4fae 100644 --- a/packages/PackageInstaller/res/values-es-rUS/strings.xml +++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"¿Quieres desinstalar esta app para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos. Esta acción afectará a todos los usuarios de este dispositivo, incluidos los que tengan perfiles de trabajo."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"También quitar <xliff:g id="SIZE">%1$s</xliff:g> de archivos multimedia asociados."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Guardar <xliff:g id="SIZE">%1$s</xliff:g> en datos de apps"</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalaciones activas"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalaciones con errores"</string> <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string> diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml index 7aef3333c13a..72351d6f494e 100644 --- a/packages/PackageInstaller/res/values-es/strings.xml +++ b/packages/PackageInstaller/res/values-es/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string> diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml index 873ac48343ed..41e428ac091d 100644 --- a/packages/PackageInstaller/res/values-et/strings.xml +++ b/packages/PackageInstaller/res/values-et/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Kas soovite selle rakenduse kasutaja <xliff:g id="USERNAME">%1$s</xliff:g> kontolt desinstallida?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse. See mõjutab kõiki seadme kasutajaid, sh neid, kellel on tööprofiilid."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Eemalda ka <xliff:g id="SIZE">%1$s</xliff:g> seotud meediafailidest."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Säilita rakenduse andmete hulk <xliff:g id="SIZE">%1$s</xliff:g>."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Käimasolevad desinstallimised"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ebaõnnestunud desinstallimised"</string> <string name="uninstalling" msgid="8709566347688966845">"Desinstallimine …"</string> diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml index 6e79ac86a957..30a366592fb4 100644 --- a/packages/PackageInstaller/res/values-eu/strings.xml +++ b/packages/PackageInstaller/res/values-eu/strings.xml @@ -58,6 +58,8 @@ <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="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-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml index 7a36387c968c..2353d4ac02a4 100644 --- a/packages/PackageInstaller/res/values-fa/strings.xml +++ b/packages/PackageInstaller/res/values-fa/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"درحال حذف نصب..."</string> diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml index b73c50b8f370..f4f1c083db34 100644 --- a/packages/PackageInstaller/res/values-fi/strings.xml +++ b/packages/PackageInstaller/res/values-fi/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Haluatko poistaa tämän sovelluksen käyttäjältä <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki data poistetaan."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki data poistetaan. Tämä vaikuttaa kaikkiin laitteen käyttäjiin, myös työprofiileihin."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Poista myös <xliff:g id="SIZE">%1$s</xliff:g> tähän liittyviä mediatiedostoja"</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Säilytä <xliff:g id="SIZE">%1$s</xliff:g> sovellusdataa"</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Käynnissä olevat poistot"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Epäonnistuneet poistot"</string> <string name="uninstalling" msgid="8709566347688966845">"Poistetaan…"</string> diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml index a6cd289223ee..78c04b3eb164 100644 --- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml +++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Désinstallation en cours…"</string> diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml index d36322ad065c..7d69edf335e5 100644 --- a/packages/PackageInstaller/res/values-fr/strings.xml +++ b/packages/PackageInstaller/res/values-fr/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Désinstallation…"</string> diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml index a7b42789cf3a..fa010c2d335a 100644 --- a/packages/PackageInstaller/res/values-gl/strings.xml +++ b/packages/PackageInstaller/res/values-gl/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Queres desinstalar esta aplicación para o usuario que se chama <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos. Isto afectará a todos os usuarios do dispositivo, incluídos os que teñan perfís de traballo."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Quitar tamén <xliff:g id="SIZE">%1$s</xliff:g> de ficheiros multimedia asociados."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Conservar os datos da aplicación, que ocupan <xliff:g id="SIZE">%1$s</xliff:g>."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalacións en curso"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Erros nas desinstalacións"</string> <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string> diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml index 66e6fd166a8c..1b7e936235f2 100644 --- a/packages/PackageInstaller/res/values-gu/strings.xml +++ b/packages/PackageInstaller/res/values-gu/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"અનઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string> diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml index 3c6031c92ad8..3ffa7e31fcea 100644 --- a/packages/PackageInstaller/res/values-hi/strings.xml +++ b/packages/PackageInstaller/res/values-hi/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"अनइंस्टॉल हो रहा है…"</string> diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml index 380df4a67327..769001a83c99 100644 --- a/packages/PackageInstaller/res/values-hr/strings.xml +++ b/packages/PackageInstaller/res/values-hr/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li deinstalirati tu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke. To se odnosi na sve korisnike uređaja, uključujući one s radnim profilima."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Ukloni i <xliff:g id="SIZE">%1$s</xliff:g> povezanih medijskih datoteka."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Zadrži <xliff:g id="SIZE">%1$s</xliff:g> podataka aplikacije."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Deinstaliranja u tijeku"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspjela deinstaliranja"</string> <string name="uninstalling" msgid="8709566347688966845">"Deinstaliranje…"</string> diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml index 9cbff8b831c6..9aceb8d2c9d3 100644 --- a/packages/PackageInstaller/res/values-hu/strings.xml +++ b/packages/PackageInstaller/res/values-hu/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Eltávolítja ezt az alkalmazást <xliff:g id="USERNAME">%1$s</xliff:g> felhasználó esetében?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik. Ez az eszköz összes felhasználóját érinti, így a munkaprofilokkal rendelkezőket is."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Távolítsa el a társított médiafájlokat is (összesen: <xliff:g id="SIZE">%1$s</xliff:g>)."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> alkalmazásadat megtartása."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Futó eltávolítások"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Sikertelen telepítések"</string> <string name="uninstalling" msgid="8709566347688966845">"Eltávolítás…"</string> diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml index 2e2c8559bff8..da1bf3cd16cb 100644 --- a/packages/PackageInstaller/res/values-hy/strings.xml +++ b/packages/PackageInstaller/res/values-hy/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Ապատեղադրվում է…"</string> diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml index fadff6148bc5..15f3b41df3ea 100644 --- a/packages/PackageInstaller/res/values-in/strings.xml +++ b/packages/PackageInstaller/res/values-in/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Apakah Anda ingin meng-uninstal aplikasi ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Ganti aplikasi ini dengan versi setelan pabrik? Semua data akan dihapus."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Ganti aplikasi ini dengan versi setelan pabrik? Semua data akan dihapus. Tindakan ini memengaruhi semua pengguna perangkat ini, termasuk yang memiliki profil kerja."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Hapus juga <xliff:g id="SIZE">%1$s</xliff:g> dari file media terkait."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Pertahankan data aplikasi sebesar <xliff:g id="SIZE">%1$s</xliff:g>."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Menjalankan proses uninstal"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Proses uninstal yang gagal"</string> <string name="uninstalling" msgid="8709566347688966845">"Meng-uninstal..."</string> diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml index a50714fe3be6..e27be00838d0 100644 --- a/packages/PackageInstaller/res/values-is/strings.xml +++ b/packages/PackageInstaller/res/values-is/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Viltu fjarlægja þetta forrit fyrir notandann <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð. Þetta hefur áhrif á alla notendur tækisins, þar á meðal þá sem eru með vinnusnið."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Fjarlægja einnig <xliff:g id="SIZE">%1$s</xliff:g> af tengdum efnisskrám."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Halda <xliff:g id="SIZE">%1$s</xliff:g> af forritagögnum."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Fjarlægingar í gangi"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Fjarlægingar sem mistókust"</string> <string name="uninstalling" msgid="8709566347688966845">"Fjarlægir…"</string> diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml index 5ca7edafb30d..9f67a58a0dae 100644 --- a/packages/PackageInstaller/res/values-it/strings.xml +++ b/packages/PackageInstaller/res/values-it/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Disinstallare l\'app per l\'utente <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi. Saranno interessati tutti gli utenti del dispositivo, inclusi quelli che hanno profili di lavoro."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Rimuovi anche <xliff:g id="SIZE">%1$s</xliff:g> di file multimediali associati."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Mantieni <xliff:g id="SIZE">%1$s</xliff:g> di dati delle app."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Disinstallazioni in esecuzione"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Disinstallazioni non riuscite"</string> <string name="uninstalling" msgid="8709566347688966845">"Disinstallazione…"</string> diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml index cd94cdaeae9b..628b33539584 100644 --- a/packages/PackageInstaller/res/values-iw/strings.xml +++ b/packages/PackageInstaller/res/values-iw/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"מסיר התקנה..."</string> diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml index 7496016e41ea..4e748bc5b6f1 100644 --- a/packages/PackageInstaller/res/values-ja/strings.xml +++ b/packages/PackageInstaller/res/values-ja/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"アンインストールしています…"</string> diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml index aac14dca4d16..fc4ba2901b8c 100644 --- a/packages/PackageInstaller/res/values-ka/strings.xml +++ b/packages/PackageInstaller/res/values-ka/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"მიმდინარეობს დეინსტალაცია…"</string> diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml index a105a005f00f..cecc482c8a27 100644 --- a/packages/PackageInstaller/res/values-kk/strings.xml +++ b/packages/PackageInstaller/res/values-kk/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Жойылуда…"</string> diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml index ce0db9108813..6bdc582efe1b 100644 --- a/packages/PackageInstaller/res/values-km/strings.xml +++ b/packages/PackageInstaller/res/values-km/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"កំពុងលុប…"</string> diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml index 4c5373eb010b..d78d3687f7a9 100644 --- a/packages/PackageInstaller/res/values-kn/strings.xml +++ b/packages/PackageInstaller/res/values-kn/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string> diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml index 1741b6e813e9..f5b4dc8a6ebe 100644 --- a/packages/PackageInstaller/res/values-ko/strings.xml +++ b/packages/PackageInstaller/res/values-ko/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"제거 중..."</string> diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml index 6b4abb9b898e..77c05b069a9b 100644 --- a/packages/PackageInstaller/res/values-ky/strings.xml +++ b/packages/PackageInstaller/res/values-ky/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Чыгарылып салынууда…"</string> diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml index aa55e3cb3200..df51634e823c 100644 --- a/packages/PackageInstaller/res/values-lo/strings.xml +++ b/packages/PackageInstaller/res/values-lo/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"ກຳລັງຖອນການຕິດຕັ້ງ..."</string> diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml index aec94c49825f..bec41451fa36 100644 --- a/packages/PackageInstaller/res/values-lt/strings.xml +++ b/packages/PackageInstaller/res/values-lt/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Ar norite pašalinti šią naudotojo <xliff:g id="USERNAME">%1$s</xliff:g> programą?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti. Tai paveiks visus šio įrenginio naudotojus, įskaitant turinčius darbo profilius."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Taip pat pašalinti <xliff:g id="SIZE">%1$s</xliff:g> susijusių medijos failų."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Palikti <xliff:g id="SIZE">%1$s</xliff:g> programų duomenų."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Vykdomi pašalinimai"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Nepavykę pašalinimai"</string> <string name="uninstalling" msgid="8709566347688966845">"Pašalinama…"</string> diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml index 76840cb35ea4..835af00c5bb9 100644 --- a/packages/PackageInstaller/res/values-lv/strings.xml +++ b/packages/PackageInstaller/res/values-lv/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Vai vēlaties atinstalēt šo lietotni lietotājam <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti. Tas ietekmēs visu šīs ierīces lietotāju datus, pat ja viņiem ir darba profili."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Noņemt arī saistītos multivides failus (<xliff:g id="SIZE">%1$s</xliff:g>)."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Iegūstiet <xliff:g id="SIZE">%1$s</xliff:g> (lietotnes dati)."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Pašreizējās atinstalēšanas operācijas"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Nesekmīgi atinstalēšanas mēģinājumi"</string> <string name="uninstalling" msgid="8709566347688966845">"Notiek atinstalēšana…"</string> diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml index 998850eb76ac..aa94284930ac 100644 --- a/packages/PackageInstaller/res/values-mk/strings.xml +++ b/packages/PackageInstaller/res/values-mk/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Се деинсталира…"</string> diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml index d2dbdcfef36f..1ef8d143a49b 100644 --- a/packages/PackageInstaller/res/values-ml/strings.xml +++ b/packages/PackageInstaller/res/values-ml/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"അണ് ഇൻസ്റ്റാൾ ചെയ്യുന്നു..."</string> diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml index 56a2128499f2..ca15978d7b71 100644 --- a/packages/PackageInstaller/res/values-mn/strings.xml +++ b/packages/PackageInstaller/res/values-mn/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Устгаж байна…"</string> diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml index 01f3e5b5bd82..218263135b20 100644 --- a/packages/PackageInstaller/res/values-mr/strings.xml +++ b/packages/PackageInstaller/res/values-mr/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"अनइंस्टॉल करत आहे…"</string> diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml index 674f55b86b38..50e00d64b900 100644 --- a/packages/PackageInstaller/res/values-ms/strings.xml +++ b/packages/PackageInstaller/res/values-ms/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Adakah anda ingin menyahpasang apl ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar. Tindakan ini melibatkan semua pengguna peranti ini, termasuk mereka yang mempunyai profil kerja."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Alih keluar juga <xliff:g id="SIZE">%1$s</xliff:g> fail media yang berkaitan."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Simpan <xliff:g id="SIZE">%1$s</xliff:g> data apl."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Penyahpasangan yang sedang berjalan"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Penyahpasangan yang gagal"</string> <string name="uninstalling" msgid="8709566347688966845">"Menyahpasang…"</string> diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml index 9c9295712b25..31c3f93dbdd7 100644 --- a/packages/PackageInstaller/res/values-my/strings.xml +++ b/packages/PackageInstaller/res/values-my/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"ပရိုဂရမ်ကို ဖယ်ရှားနေသည်..."</string> diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml index 0d3384eac5a0..34c20a1b860c 100644 --- a/packages/PackageInstaller/res/values-nb/strings.xml +++ b/packages/PackageInstaller/res/values-nb/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Ønsker du å avinstallere denne appen for brukeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes. Dette påvirker alle som bruker denne enheten – også personer med jobbprofiler."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Fjern også <xliff:g id="SIZE">%1$s</xliff:g> med tilknyttede mediefiler."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Behold <xliff:g id="SIZE">%1$s</xliff:g> med appdata."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Avinstalleringer som er i gang"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislykkede avinstalleringer"</string> <string name="uninstalling" msgid="8709566347688966845">"Avinstallerer …"</string> diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml index a7abc17f538d..e55afd5ae8df 100644 --- a/packages/PackageInstaller/res/values-ne/strings.xml +++ b/packages/PackageInstaller/res/values-ne/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"स्थापना रद्द गर्दै…"</string> diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml index a7a5a34b2e3a..8423fda2e40f 100644 --- a/packages/PackageInstaller/res/values-nl/strings.xml +++ b/packages/PackageInstaller/res/values-nl/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Wil je deze app verwijderen voor de gebruiker <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd. Dit geldt voor alle gebruikers van het apparaat, dus ook voor gebruikers met een werkprofiel."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Ook <xliff:g id="SIZE">%1$s</xliff:g> aan gekoppelde mediabestanden verwijderen."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> aan app-gegevens behouden."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Actieve verwijderingen"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislukte verwijderingen"</string> <string name="uninstalling" msgid="8709566347688966845">"Verwijderen…"</string> diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml index 348cc6109fa4..2fcf70e36c76 100644 --- a/packages/PackageInstaller/res/values-or/strings.xml +++ b/packages/PackageInstaller/res/values-or/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"ଅନ୍ଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string> diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml index 7c519a036e04..ca8f73b79746 100644 --- a/packages/PackageInstaller/res/values-pa/strings.xml +++ b/packages/PackageInstaller/res/values-pa/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"ਅਣਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string> diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml index 19b05a928e34..6bcf20a6cee2 100644 --- a/packages/PackageInstaller/res/values-pl/strings.xml +++ b/packages/PackageInstaller/res/values-pl/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Chcesz odinstalować tę aplikację dla użytkownika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte. Dotyczy to wszystkich użytkowników tego urządzenia, również tych korzystających z profilu do pracy."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Usuń też <xliff:g id="SIZE">%1$s</xliff:g> powiązanych plików multimedialnych."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Zachowaj <xliff:g id="SIZE">%1$s</xliff:g> danych aplikacji."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Aktywne odinstalowania"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Nieudane odinstalowania"</string> <string name="uninstalling" msgid="8709566347688966845">"Odinstalowuję…"</string> diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml index 1a318374e2dc..7a0c7fb01576 100644 --- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml +++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Remover também <xliff:g id="SIZE">%1$s</xliff:g> de arquivos de mídia associados."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Manter <xliff:g id="SIZE">%1$s</xliff:g> de dados do app."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Executando desinstalações"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Falha nas desinstalações"</string> <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string> diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml index e27fed56a0a6..903db3e3ddd2 100644 --- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml +++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"A desinstalar…"</string> diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml index 1a318374e2dc..7a0c7fb01576 100644 --- a/packages/PackageInstaller/res/values-pt/strings.xml +++ b/packages/PackageInstaller/res/values-pt/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Remover também <xliff:g id="SIZE">%1$s</xliff:g> de arquivos de mídia associados."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Manter <xliff:g id="SIZE">%1$s</xliff:g> de dados do app."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Executando desinstalações"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Falha nas desinstalações"</string> <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string> diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml index 8bcc96919580..620a382cb9ed 100644 --- a/packages/PackageInstaller/res/values-ro/strings.xml +++ b/packages/PackageInstaller/res/values-ro/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Dezinstalați această aplicație pentru utilizatorul <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate. Această acțiune va afecta toți utilizatorii dispozitivului, inclusiv pe cei cu profiluri de serviciu."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Eliminați și <xliff:g id="SIZE">%1$s</xliff:g> de fișiere media asociate."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Păstrează <xliff:g id="SIZE">%1$s</xliff:g> din datele aplicației."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Dezinstalări în curs"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Dezinstalări nereușite"</string> <string name="uninstalling" msgid="8709566347688966845">"Se dezinstalează…"</string> diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml index 4e5d1ac0d72f..5aba2fadcfa0 100644 --- a/packages/PackageInstaller/res/values-ru/strings.xml +++ b/packages/PackageInstaller/res/values-ru/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Удаление…"</string> diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml index 7d854dc41bca..7f67a64e919c 100644 --- a/packages/PackageInstaller/res/values-si/strings.xml +++ b/packages/PackageInstaller/res/values-si/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"අස්ථාපනය කරමින්…"</string> diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml index 36614bcc41c3..509dac5ed0b2 100644 --- a/packages/PackageInstaller/res/values-sk/strings.xml +++ b/packages/PackageInstaller/res/values-sk/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Prebieha odinštalovanie..."</string> diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml index a679e089d188..6cd7d1b7c952 100644 --- a/packages/PackageInstaller/res/values-sl/strings.xml +++ b/packages/PackageInstaller/res/values-sl/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Ali želite to aplikacijo odstraniti za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki. To vpliva na vse uporabnike te naprave, vključno s tistimi z delovnimi profili."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Odstranite tudi <xliff:g id="SIZE">%1$s</xliff:g> povezanih predstavnostnih datotek."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Obdrži <xliff:g id="SIZE">%1$s</xliff:g> podatkov aplikacije."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Odstranitve v teku"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspele odstranitve"</string> <string name="uninstalling" msgid="8709566347688966845">"Odstranjevanje …"</string> diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml index dd35024c7b37..2a592888d128 100644 --- a/packages/PackageInstaller/res/values-sq/strings.xml +++ b/packages/PackageInstaller/res/values-sq/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Dëshiron ta çinstalosh këtë aplikacion për përdoruesin <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen. Kjo ndikon te të gjithë përdoruesit e kësaj pajisjeje, duke përfshirë ata me profile të punës."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Hiq gjithashtu <xliff:g id="SIZE">%1$s</xliff:g> skedarë media të shoqëruar."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Mbaj <xliff:g id="SIZE">%1$s</xliff:g> nga të dhënat e aplikacionit."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Çinstalimet në ekzekutim"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Çinstalimet e dështuara"</string> <string name="uninstalling" msgid="8709566347688966845">"Po çinstalohet…"</string> diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml index c25b8e0fd422..7d889c4e41f7 100644 --- a/packages/PackageInstaller/res/values-sr/strings.xml +++ b/packages/PackageInstaller/res/values-sr/strings.xml @@ -58,6 +58,8 @@ <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">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени. Ово утиче на све кориснике овог уређаја, укључујући и оне са профилима за Work."</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> <string name="uninstalling" msgid="8709566347688966845">"Деинсталира се…"</string> diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml index 0c66b53cf987..9902bdaa9e7f 100644 --- a/packages/PackageInstaller/res/values-sv/strings.xml +++ b/packages/PackageInstaller/res/values-sv/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Vill du avinstallera appen för användaren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort. Detta påverkar alla som använder enheten, även dem med jobbprofiler."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Ta även bort <xliff:g id="SIZE">%1$s</xliff:g> tillhörande mediefiler."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Behåll <xliff:g id="SIZE">%1$s</xliff:g> appdata."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Avinstallationer som pågår"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Avinstallationer som misslyckats"</string> <string name="uninstalling" msgid="8709566347688966845">"Avinstallerar …"</string> diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml index 4557f662bec4..b4c2d8379710 100644 --- a/packages/PackageInstaller/res/values-sw/strings.xml +++ b/packages/PackageInstaller/res/values-sw/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Je, ungependa kuondoa programu hii kwa mtumiaji <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Ungependa kubadilisha programu hii na toleo la kiwandani? Data yote itaondolewa."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Ungependa kubadilisha programu hii na toleo la kiwandani? Data yote itaondolewa. Hatua hii itaathiri watumiaji wote wa kifaa hiki, ikiwa ni pamoja na wale walio na wasifu za kazini."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Ondoa pia faili <xliff:g id="SIZE">%1$s</xliff:g> zinazohusiana za maudhui."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Dumisha <xliff:g id="SIZE">%1$s</xliff:g> ya data ya programu."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Programu zinazoondolewa"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mara ambazo programu haikuondolewa"</string> <string name="uninstalling" msgid="8709566347688966845">"Inaondoa…"</string> diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml index dab459a35606..b69ce166f86d 100644 --- a/packages/PackageInstaller/res/values-ta/strings.xml +++ b/packages/PackageInstaller/res/values-ta/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"நிறுவல் நீக்குகிறது…"</string> diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml index 64c5da7ef36d..e13b893ac8a9 100644 --- a/packages/PackageInstaller/res/values-te/strings.xml +++ b/packages/PackageInstaller/res/values-te/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"అన్ఇన్స్టాల్ చేస్తోంది…"</string> diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml index b6595d0bd0c7..272571c829a5 100644 --- a/packages/PackageInstaller/res/values-th/strings.xml +++ b/packages/PackageInstaller/res/values-th/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"กำลังถอนการติดตั้ง…"</string> diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml index e7b15fa2688f..903b908a259e 100644 --- a/packages/PackageInstaller/res/values-tl/strings.xml +++ b/packages/PackageInstaller/res/values-tl/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Gusto mo bang i-uninstall ang app na ito para sa user na si <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data. Nakakaapekto ito sa lahat ng user ng device na ito, kabilang ang mga may profile sa trabaho."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Alisin din ang <xliff:g id="SIZE">%1$s</xliff:g> ng mga nauugnay na media file."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Panatilihin ang <xliff:g id="SIZE">%1$s</xliff:g> ng data ng app."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Mga kasalukuyang pag-uninstall"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mga hindi na-uninstall"</string> <string name="uninstalling" msgid="8709566347688966845">"Ina-uninstall…"</string> diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml index 33dbc3a9161d..e372e11c2c33 100644 --- a/packages/PackageInstaller/res/values-tr/strings.xml +++ b/packages/PackageInstaller/res/values-tr/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı kullanıcı için bu uygulamanın yüklemesini kaldırmak istiyor musunuz?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir. Bu, çalışma profilleri olan kullanıcılar da dahil olmak üzere cihazı kullanan tüm kullanıcıları etkiler."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"<xliff:g id="SIZE">%1$s</xliff:g> boyutundaki ilişkili medya dosyalarını da kaldır."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Uygulama verilerinin <xliff:g id="SIZE">%1$s</xliff:g> kadarını sakla."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Devam eden yükleme kaldırma işlemleri"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Başarısız yükleme kaldırma işlemleri"</string> <string name="uninstalling" msgid="8709566347688966845">"Yükleme kaldırılıyor…"</string> diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml index d9cb954786a8..f04ead60b6dc 100644 --- a/packages/PackageInstaller/res/values-uk/strings.xml +++ b/packages/PackageInstaller/res/values-uk/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Видалення..."</string> diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml index 61b15790c3d9..c989a7c4aef5 100644 --- a/packages/PackageInstaller/res/values-ur/strings.xml +++ b/packages/PackageInstaller/res/values-ur/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"اَن انسٹال ہو رہا ہے…"</string> diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml index dedf00c86330..3aad35d77d02 100644 --- a/packages/PackageInstaller/res/values-uz/strings.xml +++ b/packages/PackageInstaller/res/values-uz/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Haqiqatdan ham <xliff:g id="USERNAME">%1$s</xliff:g> foydalanuvchi uchun ushbu ilovani olib tashlamoqchimisiz?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha axborotlar o‘chirib tashlanadi."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha axborotlar o‘chirib tashlanadi. Bu qurilmaning barcha foydalanuvchilariga, jumladan, ularning ishchi profillariga ham ta’sir qiladi."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Shuningdek, biriktirilgan media fayllarni ham olib tashlash (<xliff:g id="SIZE">%1$s</xliff:g>)."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> hajmdagi ilova axborotlari saqlab qolinsin"</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Davom etayotganlar"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Amalga oshmaganlar"</string> <string name="uninstalling" msgid="8709566347688966845">"O‘chirilmoqda…"</string> diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml index 7043093c4347..84c02e2da658 100644 --- a/packages/PackageInstaller/res/values-vi/strings.xml +++ b/packages/PackageInstaller/res/values-vi/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"Đang gỡ cài đặt..."</string> diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml index a91f00f94f3a..04d6c3788a48 100644 --- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"正在卸载…"</string> diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml index 286e360d601c..01440aea9907 100644 --- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"正在解除安裝…"</string> diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml index b0de2c256ce3..048aa9cd6aa4 100644 --- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml @@ -58,6 +58,8 @@ <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> <string name="uninstalling" msgid="8709566347688966845">"解除安裝中…"</string> diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml index 5d2847933323..bb0405c08b12 100644 --- a/packages/PackageInstaller/res/values-zu/strings.xml +++ b/packages/PackageInstaller/res/values-zu/strings.xml @@ -58,6 +58,8 @@ <string name="uninstall_application_text_user" msgid="498072714173920526">"Ingabe ufuna ukukhiphela lolu hlelo lokusebenza kumsebenzisi ongu-<xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_update_text" msgid="863648314632448705">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa."</string> <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa. Lokhu kuthinta bonke abasebenzisi bale divayisi, abafaka labo abanamaphrofayela wokusebenza."</string> + <string name="uninstall_remove_contributed_files" msgid="2048594420923203453">"Futhi susa u-<xliff:g id="SIZE">%1$s</xliff:g> wamafayela emidiya ahlobene."</string> + <string name="uninstall_keep_data" msgid="7002379587465487550">"Gcina u-<xliff:g id="SIZE">%1$s</xliff:g> wedatha yohlelo lokusebenza."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Ukukhishwa okuqhubekayo"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ukukhishwa okuhlulekile"</string> <string name="uninstalling" msgid="8709566347688966845">"Iyakhipha..."</string> diff --git a/packages/PrintSpooler/res/values-as/strings.xml b/packages/PrintSpooler/res/values-as/strings.xml index ba4fd99e2b3c..a93fceb87959 100644 --- a/packages/PrintSpooler/res/values-as/strings.xml +++ b/packages/PrintSpooler/res/values-as/strings.xml @@ -45,12 +45,12 @@ <string name="collapse_handle" msgid="6886637989442507451">"হেণ্ডেল সংকুচিত কৰক"</string> <string name="print_button" msgid="645164566271246268">"প্ৰিণ্ট কৰক"</string> <string name="savetopdf_button" msgid="2976186791686924743">"PDFৰ জৰিয়তে ছেভ কৰক"</string> - <string name="print_options_expanded" msgid="6944679157471691859">"প্ৰিণ্ট বিকল্পসমূহ বিস্তাৰ কৰা হ\'ল"</string> - <string name="print_options_collapsed" msgid="7455930445670414332">"প্ৰিণ্ট বিকল্পসমূহ সংকুচিত কৰা হ\'ল"</string> + <string name="print_options_expanded" msgid="6944679157471691859">"প্ৰিণ্ট বিকল্পসমূহ বিস্তাৰ কৰা হ’ল"</string> + <string name="print_options_collapsed" msgid="7455930445670414332">"প্ৰিণ্ট বিকল্পসমূহ সংকুচিত কৰা হ’ল"</string> <string name="search" msgid="5421724265322228497">"সন্ধান কৰক"</string> <string name="all_printers_label" msgid="3178848870161526399">"সকলো প্ৰিণ্টাৰ"</string> <string name="add_print_service_label" msgid="5356702546188981940">"সেৱা যোগ কৰক"</string> - <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"সন্ধান বাকচটো দেখুওৱা হ\'ল"</string> + <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"সন্ধান বাকচটো দেখুওৱা হ’ল"</string> <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"সন্ধান বাকচটো ঢাক খাই আছে"</string> <string name="print_add_printer" msgid="1088656468360653455">"প্ৰিণ্টাৰ যোগ কৰক"</string> <string name="print_select_printer" msgid="7388760939873368698">"প্ৰিণ্টাৰ বাছনি কৰক"</string> diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java index d400159984a6..0a4b24c8918b 100644 --- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java @@ -165,8 +165,13 @@ public class BarChartPreference extends Preference { private void bindChartDetailsView(PreferenceViewHolder holder) { final Button detailsView = (Button) holder.findViewById(R.id.bar_chart_details); - detailsView.setText(mDetailsId); - detailsView.setOnClickListener(mDetailsOnClickListener); + if (mDetailsId == 0) { + detailsView.setVisibility(View.GONE); + } else { + detailsView.setVisibility(View.VISIBLE); + detailsView.setText(mDetailsId); + detailsView.setOnClickListener(mDetailsOnClickListener); + } } private void updateBarChart(PreferenceViewHolder holder) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index 177ba00c8a31..4f18d450462d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -484,6 +484,10 @@ public class BluetoothEventManager { return; } final CachedBluetoothDevice activeDevice = mDeviceManager.findDevice(device); + if (activeDevice == null) { + Log.w(TAG, "AclStateChangedHandler: activeDevice is null"); + return; + } final int state; switch (action) { case BluetoothDevice.ACTION_ACL_CONNECTED: diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java index 9af06702a696..4ac3ce436f82 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java +++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java @@ -31,6 +31,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; +import java.time.Clock; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -56,11 +57,18 @@ public class RecentLocationAccesses { private final PackageManager mPackageManager; private final Context mContext; private final IconDrawableFactory mDrawableFactory; + private final Clock mClock; public RecentLocationAccesses(Context context) { + this(context, Clock.systemDefaultZone()); + } + + @VisibleForTesting + RecentLocationAccesses(Context context, Clock clock) { mContext = context; mPackageManager = context.getPackageManager(); mDrawableFactory = IconDrawableFactory.newInstance(context); + mClock = clock; } /** @@ -77,7 +85,7 @@ public class RecentLocationAccesses { // Process the AppOps list and generate a preference list. ArrayList<Access> accesses = new ArrayList<>(appOpsCount); - final long now = System.currentTimeMillis(); + final long now = mClock.millis(); final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); final List<UserHandle> profiles = um.getUserProfiles(); @@ -175,7 +183,7 @@ public class RecentLocationAccesses { public final CharSequence contentDescription; public final long accessFinishTime; - private Access(String packageName, UserHandle userHandle, Drawable icon, + public Access(String packageName, UserHandle userHandle, Drawable icon, CharSequence label, CharSequence contentDescription, long accessFinishTime) { this.packageName = packageName; diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java index e5353486c23b..959f9b24133c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java @@ -15,6 +15,7 @@ */ package com.android.settingslib.media; +import android.bluetooth.BluetoothClass; import android.content.Context; import android.util.Log; @@ -33,6 +34,7 @@ public class BluetoothMediaDevice extends MediaDevice { BluetoothMediaDevice(Context context, CachedBluetoothDevice device) { super(context, MediaDeviceType.TYPE_BLUETOOTH_DEVICE); mCachedDevice = device; + initDeviceRecord(); } @Override @@ -55,6 +57,7 @@ public class BluetoothMediaDevice extends MediaDevice { public void connect() { //TODO(b/117129183): add callback to notify LocalMediaManager connection state. mIsConnected = mCachedDevice.setActive(); + super.connect(); Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected); } @@ -70,4 +73,18 @@ public class BluetoothMediaDevice extends MediaDevice { public CachedBluetoothDevice getCachedDevice() { return mCachedDevice; } + + @Override + protected boolean isCarKitDevice() { + final BluetoothClass bluetoothClass = mCachedDevice.getDevice().getBluetoothClass(); + if (bluetoothClass != null) { + switch (bluetoothClass.getDeviceClass()) { + // Both are common CarKit class + case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: + case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: + return true; + } + } + return false; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java index 04188e936cf6..ab1cca0084c4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java @@ -75,6 +75,7 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall Log.w(TAG, "addConnectedA2dpDevices() a2dp profile is null!"); return; } + final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices(); final CachedBluetoothDeviceManager cachedBluetoothDeviceManager = mLocalBluetoothManager.getCachedDeviceManager(); @@ -103,6 +104,7 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall Log.w(TAG, "addConnectedA2dpDevices() hap profile is null!"); return; } + final List<Long> devicesHiSyncIds = new ArrayList<>(); final List<BluetoothDevice> devices = hapProfile.getConnectedDevices(); final CachedBluetoothDeviceManager cachedBluetoothDeviceManager = @@ -185,7 +187,7 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall private boolean isCachedDeviceConnected(CachedBluetoothDevice cachedDevice) { final boolean isConnectedHearingAidDevice = cachedDevice.isConnectedHearingAidDevice(); final boolean isConnectedA2dpDevice = cachedDevice.isConnectedA2dpDevice(); - Log.d(TAG, "isCachedDeviceConnected() cachedDevice : " + cachedDevice.getName() + Log.d(TAG, "isCachedDeviceConnected() cachedDevice : " + cachedDevice + ", is hearing aid connected : " + isConnectedHearingAidDevice + ", is a2dp connected : " + isConnectedA2dpDevice); @@ -226,7 +228,7 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall @Override public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state, int bluetoothProfile) { - Log.d(TAG, "onProfileConnectionStateChanged() device: " + cachedDevice.getName() + Log.d(TAG, "onProfileConnectionStateChanged() device: " + cachedDevice + ", state: " + state + ", bluetoothProfile: " + bluetoothProfile); if (isCachedDeviceConnected(cachedDevice)) { @@ -240,8 +242,7 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall @Override public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { - Log.d(TAG, "onAclConnectionStateChanged() device: " + cachedDevice.getName() - + ", state: " + state); + Log.d(TAG, "onAclConnectionStateChanged() device: " + cachedDevice + ", state: " + state); if (isCachedDeviceConnected(cachedDevice)) { addMediaDevice(cachedDevice); @@ -251,7 +252,6 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall dispatchDeviceRemoved(cachedDevice); } } - class DeviceAttributeChangeCallback implements CachedBluetoothDevice.Callback { @Override public void onDeviceAttributesChanged() { diff --git a/packages/SettingsLib/src/com/android/settingslib/media/ConnectionRecordManager.java b/packages/SettingsLib/src/com/android/settingslib/media/ConnectionRecordManager.java new file mode 100644 index 000000000000..af343c4980bf --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/media/ConnectionRecordManager.java @@ -0,0 +1,89 @@ +/* + * 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 com.android.settingslib.media; + +import android.content.Context; +import android.content.SharedPreferences; + +/** + * ConnectionRecordManager represents the sharedPreferences operation on device usage record + */ +public class ConnectionRecordManager { + private static final Object sInstanceSync = new Object(); + private static final String KEY_LAST_SELECTED_DEVICE = "last_selected_device"; + private static final String SHARED_PREFERENCES_NAME = "seamless_transfer_record"; + private static final String TAG = "ConnectionRecordManager"; + private static ConnectionRecordManager sInstance; + + private String mLastSelectedDevice; + + /** + * Get an {@code ConnectionRecordManager} instance (create one if necessary). + */ + public static ConnectionRecordManager getInstance() { + synchronized (sInstanceSync) { + if (sInstance == null) { + sInstance = new ConnectionRecordManager(); + } + } + return sInstance; + } + + private SharedPreferences getSharedPreferences(Context context) { + return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + } + + /** + * Get connection record from sharedPreferences + * + * @param id a unique device Id + * @return the the usage result + */ + public synchronized int fetchConnectionRecord(Context context, String id) { + return getSharedPreferences(context).getInt(id, 0); + } + + /** + * Get the last selected device from sharedPreferences + */ + public synchronized void fetchLastSelectedDevice(Context context) { + mLastSelectedDevice = getSharedPreferences(context).getString(KEY_LAST_SELECTED_DEVICE, + null); + } + + /** + * Set device usage time and last selected device in sharedPreference + * + * @param id a unique device Id + * @param record usage times + */ + public synchronized void setConnectionRecord(Context context, String id, int record) { + final SharedPreferences.Editor editor = getSharedPreferences(context).edit(); + // Update used times + mLastSelectedDevice = id; + editor.putInt(mLastSelectedDevice, record); + // Update last used device + editor.putString(KEY_LAST_SELECTED_DEVICE, mLastSelectedDevice); + editor.apply(); + } + + /** + * @return the last selected device + */ + public synchronized String getLastSelectedDevice() { + return mLastSelectedDevice; + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java index 498a0fc4d8b2..21a81e03037a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java @@ -33,6 +33,7 @@ public class InfoMediaDevice extends MediaDevice { InfoMediaDevice(Context context, MediaRouter.RouteInfo info) { super(context, MediaDeviceType.TYPE_CAST_DEVICE); mRouteInfo = info; + initDeviceRecord(); } @Override @@ -55,6 +56,7 @@ public class InfoMediaDevice extends MediaDevice { public void connect() { //TODO(b/117129183): use MediaController2 to transfer media mIsConnected = true; + super.connect(); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index e375ea016ec2..c9479d44f791 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -28,13 +28,15 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /** * LocalMediaManager provide interface to get MediaDevice list and transfer media to MediaDevice. */ public class LocalMediaManager implements BluetoothCallback { - + private static final Comparator<MediaDevice> COMPARATOR = Comparator.naturalOrder(); private static final String TAG = "LocalMediaManager"; @Retention(RetentionPolicy.SOURCE) @@ -153,6 +155,7 @@ public class LocalMediaManager implements BluetoothCallback { void dispatchDeviceListUpdate() { synchronized (mCallbacks) { + Collections.sort(mMediaDevices, COMPARATOR); for (DeviceCallback callback : mCallbacks) { callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices)); } @@ -169,6 +172,23 @@ public class LocalMediaManager implements BluetoothCallback { mInfoMediaManager.stopScan(); } + /** + * Find the MediaDevice through id. + * + * @param devices the list of MediaDevice + * @param id the unique id of MediaDevice + * @return MediaDevice + */ + public MediaDevice getMediaDeviceById(List<MediaDevice> devices, String id) { + for (MediaDevice mediaDevice : devices) { + if (mediaDevice.getId().equals(id)) { + return mediaDevice; + } + } + Log.i(TAG, "getMediaDeviceById() can't found device"); + return null; + } + class MediaDeviceCallback implements MediaManager.MediaDeviceCallback { @Override public void onDeviceAdded(MediaDevice device) { diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java index b1c4f14b6aaf..33b621cb28da 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java @@ -16,6 +16,7 @@ package com.android.settingslib.media; import android.content.Context; +import android.text.TextUtils; import androidx.annotation.IntDef; @@ -25,20 +26,21 @@ import java.lang.annotation.RetentionPolicy; /** * MediaDevice represents a media device(such like Bluetooth device, cast device and phone device). */ -public abstract class MediaDevice { - +public abstract class MediaDevice implements Comparable<MediaDevice> { private static final String TAG = "MediaDevice"; @Retention(RetentionPolicy.SOURCE) - @IntDef({MediaDeviceType.TYPE_BLUETOOTH_DEVICE, - MediaDeviceType.TYPE_CAST_DEVICE, + @IntDef({MediaDeviceType.TYPE_CAST_DEVICE, + MediaDeviceType.TYPE_BLUETOOTH_DEVICE, MediaDeviceType.TYPE_PHONE_DEVICE}) public @interface MediaDeviceType { - int TYPE_BLUETOOTH_DEVICE = 1; - int TYPE_CAST_DEVICE = 2; + int TYPE_CAST_DEVICE = 1; + int TYPE_BLUETOOTH_DEVICE = 2; int TYPE_PHONE_DEVICE = 3; } + private int mConnectedRecord; + protected boolean mIsConnected = false; protected Context mContext; protected int mType; @@ -48,6 +50,12 @@ public abstract class MediaDevice { mContext = context; } + void initDeviceRecord() { + ConnectionRecordManager.getInstance().fetchLastSelectedDevice(mContext); + mConnectedRecord = ConnectionRecordManager.getInstance().fetchConnectionRecord(mContext, + getId()); + } + /** * Check the MediaDevice is be connected to transfer. * @@ -80,10 +88,71 @@ public abstract class MediaDevice { /** * Transfer MediaDevice for media */ - public abstract void connect(); + public void connect() { + mConnectedRecord++; + ConnectionRecordManager.getInstance().setConnectionRecord(mContext, getId(), + mConnectedRecord); + } /** * Stop transfer MediaDevice */ public abstract void disconnect(); + + /** + * Rules: + * 1. If there is one of the connected devices identified as a carkit, this carkit will + * be always on the top of the device list. Rule 2 and Rule 3 can’t overrule this rule. + * 2. For devices without any usage data yet + * WiFi device group sorted by alphabetical order + BT device group sorted by alphabetical + * order + phone speaker + * 3. For devices with usage record. + * The most recent used one + device group with usage info sorted by how many times the + * device has been used. + * + * So the device list will look like 4 slots ranked as below. + * Rule 1 + the most recently used device + Rule 3 + Rule 2 + * Any slot could be empty. And available device will belong to one of the slots. + * + * @return a negative integer, zero, or a positive integer + * as this object is less than, equal to, or greater than the specified object. + */ + @Override + public int compareTo(MediaDevice another) { + // Check carkit + if (isCarKitDevice()) { + return -1; + } else if (another.isCarKitDevice()) { + return 1; + } + // Set last used device at the first item + String lastSelectedDevice = ConnectionRecordManager.getInstance().getLastSelectedDevice(); + if (TextUtils.equals(lastSelectedDevice, getId())) { + return -1; + } else if (TextUtils.equals(lastSelectedDevice, another.getId())) { + return 1; + } + // Sort by how many times the device has been used if there is usage record + if ((mConnectedRecord != another.mConnectedRecord) + && (another.mConnectedRecord > 0 || mConnectedRecord > 0)) { + return (another.mConnectedRecord - mConnectedRecord); + } + // Both devices have never been used + // To devices with the same type, sort by alphabetical order + if (mType == another.mType) { + final String s1 = getName(); + final String s2 = another.getName(); + return s1.compareToIgnoreCase(s2); + } + // Both devices have never been used, the priority is Cast > Bluetooth > Phone + return mType - another.mType; + } + + /** + * Check if it is CarKit device + * @return true if it is CarKit device + */ + protected boolean isCarKitDevice() { + return false; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java index 060e9ad3368f..bdddaf394f89 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java @@ -23,7 +23,6 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice; * MediaDeviceUtils provides utility function for MediaDevice */ public class MediaDeviceUtils { - /** * Use CachedBluetoothDevice address to represent unique id * diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java index 5e49d6b49e11..e0f3c2ff7692 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java @@ -41,6 +41,7 @@ public class PhoneMediaDevice extends MediaDevice { mLocalBluetoothManager = localBluetoothManager; mProfileManager = mLocalBluetoothManager.getProfileManager(); + initDeviceRecord(); } @Override @@ -66,8 +67,8 @@ public class PhoneMediaDevice extends MediaDevice { final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile(); if (hapProfile != null && a2dpProfile != null) { - mIsConnected = - hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null); + mIsConnected = hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null); + super.connect(); } Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected); } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index 089f773ec1e9..871e2485a742 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -101,6 +101,9 @@ public class WifiStatusTracker extends ConnectivityManager.NetworkCallback { } public void handleBroadcast(Intent intent) { + if (mWifiManager == null) { + return; + } String action = intent.getAction(); if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { updateWifiState(); diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 2f082b959e68..e47ca3226cfb 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -212,7 +212,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro mConnectivityManager = connectivityManager; // check if verbose logging developer option has been turned on or off - sVerboseLogging = (mWifiManager.getVerboseLoggingLevel() > 0); + sVerboseLogging = mWifiManager != null && (mWifiManager.getVerboseLoggingLevel() > 0); mFilter = filter; @@ -283,7 +283,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro mScanner = new Scanner(); } - if (mWifiManager.isWifiEnabled()) { + if (isWifiEnabled()) { mScanner.resume(); } } @@ -413,7 +413,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro } public boolean isWifiEnabled() { - return mWifiManager.isWifiEnabled(); + return mWifiManager != null && mWifiManager.isWifiEnabled(); } /** @@ -638,7 +638,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro private void updateNetworkInfo(NetworkInfo networkInfo) { /* Sticky broadcasts can call this when wifi is disabled */ - if (!mWifiManager.isWifiEnabled()) { + if (!isWifiEnabled()) { clearAccessPointsAndConditionallyUpdate(); return; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java index 0dcdaed67cd6..2c70cbbe6ecb 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java @@ -181,4 +181,17 @@ public class BluetoothEventManagerTest { verify(mBluetoothCallback, never()).onAclConnectionStateChanged(mCachedBluetoothDevice, BluetoothAdapter.STATE_CONNECTED); } + + @Test + public void dispatchAclConnectionStateChanged_findDeviceReturnNull_shouldNotDispatchCallback() { + when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(null); + mBluetoothEventManager.registerCallback(mBluetoothCallback); + mIntent = new Intent(BluetoothDevice.ACTION_ACL_CONNECTED); + mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice); + + mContext.sendBroadcast(mIntent); + + verify(mBluetoothCallback, never()).onAclConnectionStateChanged(mCachedBluetoothDevice, + BluetoothAdapter.STATE_CONNECTED); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java new file mode 100644 index 000000000000..d5b89ca719ad --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java @@ -0,0 +1,162 @@ +package com.android.settingslib.location; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.AppOpsManager; +import android.app.AppOpsManager.OpEntry; +import android.app.AppOpsManager.PackageOps; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Process; +import android.os.UserHandle; +import android.os.UserManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.time.Clock; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@RunWith(RobolectricTestRunner.class) +public class RecentLocationAccessesTest { + + private static final int TEST_UID = 1234; + private static final long NOW = 1_000_000_000; // Approximately 9/8/2001 + private static final long ONE_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(1); + private static final long TWENTY_THREE_HOURS_AGO = NOW - TimeUnit.HOURS.toMillis(23); + private static final long TWO_DAYS_AGO = NOW - TimeUnit.DAYS.toMillis(2); + private static final String[] TEST_PACKAGE_NAMES = + {"package_1MinAgo", "package_14MinAgo", "package_20MinAgo"}; + + @Mock + private PackageManager mPackageManager; + @Mock + private AppOpsManager mAppOpsManager; + @Mock + private UserManager mUserManager; + @Mock + private Clock mClock; + private Context mContext; + private int mTestUserId; + private RecentLocationAccesses mRecentLocationAccesses; + + @Before + public void setUp() throws NameNotFoundException { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); + when(mPackageManager.getApplicationLabel(isA(ApplicationInfo.class))) + .thenReturn("testApplicationLabel"); + when(mPackageManager.getUserBadgedLabel(isA(CharSequence.class), isA(UserHandle.class))) + .thenReturn("testUserBadgedLabel"); + mTestUserId = UserHandle.getUserId(TEST_UID); + when(mUserManager.getUserProfiles()) + .thenReturn(Collections.singletonList(new UserHandle(mTestUserId))); + + long[] testRequestTime = {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO}; + List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime); + when(mAppOpsManager.getPackagesForOps(RecentLocationAccesses.LOCATION_OPS)).thenReturn( + appOps); + mockTestApplicationInfos(mTestUserId, TEST_PACKAGE_NAMES); + + when(mClock.millis()).thenReturn(NOW); + mRecentLocationAccesses = new RecentLocationAccesses(mContext, mClock); + } + + @Test + public void testGetAppList_shouldFilterRecentAccesses() { + List<RecentLocationAccesses.Access> requests = mRecentLocationAccesses.getAppList(); + // Only two of the apps have requested location within 15 min. + assertThat(requests).hasSize(2); + // Make sure apps are ordered by recency + assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]); + assertThat(requests.get(0).accessFinishTime).isEqualTo(ONE_MIN_AGO); + assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]); + assertThat(requests.get(1).accessFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO); + } + + @Test + public void testGetAppList_shouldNotShowAndroidOS() throws NameNotFoundException { + // Add android OS to the list of apps. + PackageOps androidSystemPackageOps = + createPackageOps( + RecentLocationAccesses.ANDROID_SYSTEM_PACKAGE_NAME, + Process.SYSTEM_UID, + AppOpsManager.OP_FINE_LOCATION, + ONE_MIN_AGO); + long[] testRequestTime = + {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO, ONE_MIN_AGO}; + List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime); + appOps.add(androidSystemPackageOps); + when(mAppOpsManager.getPackagesForOps(RecentLocationAccesses.LOCATION_OPS)).thenReturn( + appOps); + mockTestApplicationInfos( + Process.SYSTEM_UID, RecentLocationAccesses.ANDROID_SYSTEM_PACKAGE_NAME); + + List<RecentLocationAccesses.Access> requests = mRecentLocationAccesses.getAppList(); + // Android OS shouldn't show up in the list of apps. + assertThat(requests).hasSize(2); + // Make sure apps are ordered by recency + assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]); + assertThat(requests.get(0).accessFinishTime).isEqualTo(ONE_MIN_AGO); + assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]); + assertThat(requests.get(1).accessFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO); + } + + private void mockTestApplicationInfos(int userId, String... packageNameList) + throws NameNotFoundException { + for (String packageName : packageNameList) { + ApplicationInfo appInfo = new ApplicationInfo(); + appInfo.packageName = packageName; + when(mPackageManager.getApplicationInfoAsUser( + packageName, PackageManager.GET_META_DATA, userId)).thenReturn(appInfo); + } + } + + private List<PackageOps> createTestPackageOpsList(String[] packageNameList, long[] time) { + List<PackageOps> packageOpsList = new ArrayList<>(); + for (int i = 0; i < packageNameList.length; i++) { + PackageOps packageOps = createPackageOps( + packageNameList[i], + TEST_UID, + AppOpsManager.OP_FINE_LOCATION, + time[i]); + packageOpsList.add(packageOps); + } + return packageOpsList; + } + + private PackageOps createPackageOps(String packageName, int uid, int op, long time) { + return new PackageOps( + packageName, + uid, + Collections.singletonList(createOpEntryWithTime(op, time))); + } + + private OpEntry createOpEntryWithTime(int op, long time) { + final long[] times = new long[AppOpsManager._NUM_UID_STATE]; + // Slot for background access timestamp. + times[AppOpsManager.UID_STATE_LAST_NON_RESTRICTED + 1] = time; + final long[] rejectTimes = new long[AppOpsManager._NUM_UID_STATE]; + return new OpEntry(op, AppOpsManager.MODE_ALLOWED, times, rejectTimes, 0 /* duration */, + 0 /* proxyUid */, "" /* proxyPackage */); + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java new file mode 100644 index 000000000000..9bbdd0102fad --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java @@ -0,0 +1,261 @@ +/* + * 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 com.android.settingslib.media; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; +import android.content.Context; + +import androidx.mediarouter.media.MediaRouter; + +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.LocalBluetoothManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +public class MediaDeviceTest { + private static final Comparator<MediaDevice> COMPARATOR = Comparator.naturalOrder(); + private static final String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11"; + private static final String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22"; + private static final String DEVICE_ADDRESS_3 = "AA:BB:CC:DD:EE:33"; + private static final String DEVICE_NAME_1 = "TestName_1"; + private static final String DEVICE_NAME_2 = "TestName_2"; + private static final String DEVICE_NAME_3 = "TestName_3"; + private static final String ROUTER_ID_1 = "RouterId_1"; + private static final String ROUTER_ID_2 = "RouterId_2"; + private static final String ROUTER_ID_3 = "RouterId_3"; + private final BluetoothClass mHeadreeClass = + new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES); + private final BluetoothClass mCarkitClass = + new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO); + + @Mock + private BluetoothDevice mDevice1; + @Mock + private BluetoothDevice mDevice2; + @Mock + private BluetoothDevice mDevice3; + @Mock + private CachedBluetoothDevice mCachedDevice1; + @Mock + private CachedBluetoothDevice mCachedDevice2; + @Mock + private CachedBluetoothDevice mCachedDevice3; + @Mock + private LocalBluetoothManager mLocalBluetoothManager; + @Mock + private MediaRouter.RouteInfo mRouteInfo1; + @Mock + private MediaRouter.RouteInfo mRouteInfo2; + @Mock + private MediaRouter.RouteInfo mRouteInfo3; + + private BluetoothMediaDevice mBluetoothMediaDevice1; + private BluetoothMediaDevice mBluetoothMediaDevice2; + private BluetoothMediaDevice mBluetoothMediaDevice3; + private Context mContext; + private InfoMediaDevice mInfoMediaDevice1; + private InfoMediaDevice mInfoMediaDevice2; + private InfoMediaDevice mInfoMediaDevice3; + private List<MediaDevice> mMediaDevices = new ArrayList<>(); + private PhoneMediaDevice mPhoneMediaDevice; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + + when(mCachedDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1); + when(mCachedDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2); + when(mCachedDevice3.getAddress()).thenReturn(DEVICE_ADDRESS_3); + when(mCachedDevice1.getName()).thenReturn(DEVICE_NAME_1); + when(mCachedDevice2.getName()).thenReturn(DEVICE_NAME_2); + when(mCachedDevice3.getName()).thenReturn(DEVICE_NAME_3); + when(mCachedDevice1.getDevice()).thenReturn(mDevice1); + when(mCachedDevice2.getDevice()).thenReturn(mDevice2); + when(mCachedDevice3.getDevice()).thenReturn(mDevice3); + when(mRouteInfo1.getId()).thenReturn(ROUTER_ID_1); + when(mRouteInfo2.getId()).thenReturn(ROUTER_ID_2); + when(mRouteInfo3.getId()).thenReturn(ROUTER_ID_3); + when(mRouteInfo1.getName()).thenReturn(DEVICE_NAME_1); + when(mRouteInfo2.getName()).thenReturn(DEVICE_NAME_2); + when(mRouteInfo3.getName()).thenReturn(DEVICE_NAME_3); + + mBluetoothMediaDevice1 = new BluetoothMediaDevice(mContext, mCachedDevice1); + mBluetoothMediaDevice2 = new BluetoothMediaDevice(mContext, mCachedDevice2); + mBluetoothMediaDevice3 = new BluetoothMediaDevice(mContext, mCachedDevice3); + mInfoMediaDevice1 = new InfoMediaDevice(mContext, mRouteInfo1); + mInfoMediaDevice2 = new InfoMediaDevice(mContext, mRouteInfo2); + mInfoMediaDevice3 = new InfoMediaDevice(mContext, mRouteInfo3); + mPhoneMediaDevice = new PhoneMediaDevice(mContext, mLocalBluetoothManager); + } + + @Test + public void compareTo_carKit_nonCarKitBluetooth_carKitFirst() { + when(mDevice1.getBluetoothClass()).thenReturn(mHeadreeClass); + when(mDevice2.getBluetoothClass()).thenReturn(mCarkitClass); + mMediaDevices.add(mBluetoothMediaDevice1); + mMediaDevices.add(mBluetoothMediaDevice2); + + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2); + } + + @Test + public void compareTo_carKit_info_carKitFirst() { + when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass); + mMediaDevices.add(mInfoMediaDevice1); + mMediaDevices.add(mBluetoothMediaDevice1); + + assertThat(mMediaDevices.get(0)).isEqualTo(mInfoMediaDevice1); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + } + + @Test + public void compareTo_carKit_phone_carKitFirst() { + when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass); + mMediaDevices.add(mPhoneMediaDevice); + mMediaDevices.add(mBluetoothMediaDevice1); + + assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + } + + @Test + public void compareTo_lastSelected_others_lastSelectedFirst() { + mMediaDevices.add(mBluetoothMediaDevice1); + mMediaDevices.add(mBluetoothMediaDevice2); + mBluetoothMediaDevice2.connect(); + + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2); + } + @Test + public void compareTo_connectionRecord_sortByRecord() { + mMediaDevices.add(mBluetoothMediaDevice1); + mMediaDevices.add(mBluetoothMediaDevice2); + mBluetoothMediaDevice1.connect(); + mBluetoothMediaDevice2.connect(); + mBluetoothMediaDevice2.connect(); + // Reset last selected record + ConnectionRecordManager.getInstance().setConnectionRecord(mContext, null, 0); + + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice2); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2); + assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice1); + } + + @Test + public void compareTo_info_bluetooth_infoFirst() { + mMediaDevices.add(mBluetoothMediaDevice1); + mMediaDevices.add(mInfoMediaDevice1); + + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mInfoMediaDevice1); + } + + @Test + public void compareTo_bluetooth_phone_bluetoothFirst() { + mMediaDevices.add(mPhoneMediaDevice); + mMediaDevices.add(mBluetoothMediaDevice1); + + assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + } + + @Test + public void compareTo_twoInfo_sortByAlphabet() { + mMediaDevices.add(mInfoMediaDevice2); + mMediaDevices.add(mInfoMediaDevice1); + + assertThat(mMediaDevices.get(0)).isEqualTo(mInfoMediaDevice2); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mInfoMediaDevice1); + } + + @Test + public void compareTo_twoBluetooth_sortByAlphabet() { + mMediaDevices.add(mBluetoothMediaDevice2); + mMediaDevices.add(mBluetoothMediaDevice1); + + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2); + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + } + + // 1.mInfoMediaDevice1: Last Selected device + // 2.mBluetoothMediaDevice1: CarKit device + // 3.mInfoMediaDevice2: * 2 times usage + // 4.mInfoMediaDevice3: * 1 time usage + // 5.mBluetoothMediaDevice2: * 2 times usage + // 6.mBluetoothMediaDevice3: * 1 time usage + // 7.mPhoneMediaDevice: * 0 time usage + // Order: 2 -> 1 -> 3 -> 5 -> 4 -> 6 -> 7 + @Test + public void compareTo_mixedDevices_carKitFirst() { + when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass); + when(mDevice2.getBluetoothClass()).thenReturn(mHeadreeClass); + when(mDevice3.getBluetoothClass()).thenReturn(mHeadreeClass); + mMediaDevices.add(mBluetoothMediaDevice1); + mMediaDevices.add(mBluetoothMediaDevice2); + mMediaDevices.add(mBluetoothMediaDevice3); + mMediaDevices.add(mInfoMediaDevice1); + mMediaDevices.add(mInfoMediaDevice2); + mMediaDevices.add(mInfoMediaDevice3); + mMediaDevices.add(mPhoneMediaDevice); + mBluetoothMediaDevice3.connect(); + mBluetoothMediaDevice2.connect(); + mBluetoothMediaDevice2.connect(); + mInfoMediaDevice3.connect(); + mInfoMediaDevice2.connect(); + mInfoMediaDevice2.connect(); + mInfoMediaDevice1.connect(); + + Collections.sort(mMediaDevices, COMPARATOR); + assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1); + assertThat(mMediaDevices.get(1)).isEqualTo(mInfoMediaDevice1); + assertThat(mMediaDevices.get(2)).isEqualTo(mInfoMediaDevice2); + assertThat(mMediaDevices.get(3)).isEqualTo(mBluetoothMediaDevice2); + assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice3); + assertThat(mMediaDevices.get(5)).isEqualTo(mBluetoothMediaDevice3); + assertThat(mMediaDevices.get(6)).isEqualTo(mPhoneMediaDevice); + } + +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java index d4e74810ea3f..96e8995579f7 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java @@ -41,6 +41,7 @@ public class BarChartPreferenceTest { private BarView mBarView2; private BarView mBarView3; private BarView mBarView4; + private TextView mDetailsView; private PreferenceViewHolder mHolder; private BarChartPreference mPreference; @@ -51,14 +52,13 @@ public class BarChartPreferenceTest { mHolder = PreferenceViewHolder.createInstanceForTests(mBarChartView); mPreference = new BarChartPreference(mContext, null /* attrs */); mPreference.setBarChartTitle(R.string.debug_app); - mPreference.setBarChartDetails(R.string.debug_app); - mIcon = mContext.getDrawable(R.drawable.ic_menu); mBarView1 = (BarView) mBarChartView.findViewById(R.id.bar_view1); mBarView2 = (BarView) mBarChartView.findViewById(R.id.bar_view2); mBarView3 = (BarView) mBarChartView.findViewById(R.id.bar_view3); mBarView4 = (BarView) mBarChartView.findViewById(R.id.bar_view4); + mDetailsView = (TextView) mBarChartView.findViewById(R.id.bar_chart_details); } @Test @@ -73,26 +73,45 @@ public class BarChartPreferenceTest { } @Test - public void setBarChartDetailsRes_setDetailsRes_showInBarChartDetails() { - final TextView detailsView = (TextView) mBarChartView.findViewById(R.id.bar_chart_details); + public void onBindViewHolder_notSetDetailsRes_barChartDetailsViewIsGone() { + // We don't call BarChartPreference#setBarChartDetails + mPreference.onBindViewHolder(mHolder); + + assertThat(mDetailsView.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void onBindViewHolder_notSetDetailsRes_barChartDetailsViewIsGoneThenReappears() { + // We don't call BarChartPreference#setBarChartDetails yet. + mPreference.onBindViewHolder(mHolder); + + assertThat(mDetailsView.getVisibility()).isEqualTo(View.GONE); mPreference.setBarChartDetails(R.string.debug_app); mPreference.onBindViewHolder(mHolder); - assertThat(detailsView.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(detailsView.getText()).isEqualTo(mContext.getText(R.string.debug_app)); + assertThat(mDetailsView.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mDetailsView.getText()).isEqualTo(mContext.getText(R.string.debug_app)); } @Test - public void setBarChartDetailsClickListener_setClickListener_detailsViewAttachClickListener() { - final TextView detailsView = (TextView) mBarChartView.findViewById(R.id.bar_chart_details); + public void setBarChartDetailsRes_setDetailsRes_showInBarChartDetails() { + mPreference.setBarChartDetails(R.string.debug_app); + mPreference.onBindViewHolder(mHolder); + assertThat(mDetailsView.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mDetailsView.getText()).isEqualTo(mContext.getText(R.string.debug_app)); + } + + @Test + public void setBarChartDetailsClickListener_setClickListener_detailsViewAttachClickListener() { + mPreference.setBarChartDetails(R.string.debug_app); mPreference.setBarChartDetailsClickListener(v -> { }); mPreference.onBindViewHolder(mHolder); - assertThat(detailsView.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(detailsView.hasOnClickListeners()).isTrue(); + assertThat(mDetailsView.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mDetailsView.hasOnClickListeners()).isTrue(); } @Test diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk index 0d681ed0f37a..ac97adb2c5c5 100644 --- a/packages/SettingsProvider/test/Android.mk +++ b/packages/SettingsProvider/test/Android.mk @@ -10,7 +10,7 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) \ ../src/com/android/providers/settings/SettingsState.java \ ../src/com/android/providers/settings/SettingsHelper.java -LOCAL_STATIC_JAVA_LIBRARIES := android-support-test +LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules LOCAL_JAVA_LIBRARIES := android.test.base diff --git a/packages/SettingsProvider/test/AndroidManifest.xml b/packages/SettingsProvider/test/AndroidManifest.xml index 71e0b153daa9..87a4f603f70b 100644 --- a/packages/SettingsProvider/test/AndroidManifest.xml +++ b/packages/SettingsProvider/test/AndroidManifest.xml @@ -29,7 +29,7 @@ </application> <instrumentation - android:name="android.support.test.runner.AndroidJUnitRunner" + android:name="androidx.test.runner.AndroidJUnitRunner" android:targetPackage="com.android.providers.setting.test" android:label="Settings Provider Tests" /> diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml index 46b8f94f23a3..9d2352670ddd 100644 --- a/packages/SettingsProvider/test/AndroidTest.xml +++ b/packages/SettingsProvider/test/AndroidTest.xml @@ -22,7 +22,7 @@ <option name="test-tag" value="SettingsProviderTest" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.providers.setting.test" /> - <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java index ab23af39b98f..68efa6779f04 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java @@ -25,9 +25,12 @@ import android.net.Uri; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + import libcore.io.Streams; + import org.junit.runner.RunWith; import java.io.FileInputStream; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java index 5587cba59150..df4656a6deeb 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java @@ -24,8 +24,9 @@ import android.content.ContentResolver; import android.os.Bundle; import android.provider.DeviceConfig; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import libcore.io.Streams; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java index d8ee9b64c7d9..863b0352913a 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java @@ -26,10 +26,11 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserManager; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.LargeTest; import android.util.Log; +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; + import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java index 10749571b623..54f8688bf5d6 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java @@ -24,8 +24,10 @@ import android.content.Context; import android.net.Uri; import android.os.Build; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java index 6fa014d4bef7..d112facc2b0e 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java @@ -17,19 +17,10 @@ package com.android.providers.settings; import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertSame; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.fail; - -import com.android.internal.app.LocalePicker; -import com.android.providers.settings.SettingsHelper; import android.os.LocaleList; -import android.support.test.runner.AndroidJUnit4; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/Shell/res/values-as/strings.xml b/packages/Shell/res/values-as/strings.xml index 0e59223857c3..6e80931e3619 100644 --- a/packages/Shell/res/values-as/strings.xml +++ b/packages/Shell/res/values-as/strings.xml @@ -19,7 +19,7 @@ <string name="app_label" msgid="3701846017049540910">"শ্বেল"</string> <string name="bugreport_notification_channel" msgid="2574150205913861141">"বাগ সম্পৰ্কীয় প্ৰতিবেদন"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"বাগ সম্পর্কীয় অভিযোগ <xliff:g id="ID">#%d</xliff:g> সৃষ্টি কৰি থকা হৈছে"</string> - <string name="bugreport_finished_title" msgid="4429132808670114081">"বাগ সম্পর্কীয় অভিযোগ <xliff:g id="ID">#%d</xliff:g> ৰেকৰ্ড কৰা হ\'ল"</string> + <string name="bugreport_finished_title" msgid="4429132808670114081">"বাগ সম্পর্কীয় অভিযোগ <xliff:g id="ID">#%d</xliff:g> ৰেকৰ্ড কৰা হ’ল"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"বাগ সম্পর্কীয় অভিযোগটোত বিশদ তথ্য যোগ কৰি থকা হৈছে"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"অনুগ্রহ কৰি অপেক্ষা কৰক…"</string> <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"ফ\'নত বাগ সম্পর্কীয় অভিযোগ অতি সোনকালে উপলব্ধ হ\'ব"</string> diff --git a/packages/SystemUI/docs/dagger.md b/packages/SystemUI/docs/dagger.md index f81e8cce1f91..cca2d13521ce 100644 --- a/packages/SystemUI/docs/dagger.md +++ b/packages/SystemUI/docs/dagger.md @@ -6,6 +6,8 @@ to create dependencies without reflection* Go read about Dagger 2. + - [User's guide](https://google.github.io/dagger/users-guide) + TODO: Add some links. ## State of the world @@ -36,7 +38,8 @@ public interface SystemUIRootComponent { The root modules are what provides the global singleton dependencies across SystemUI. ContextHolder is just a wrapper that provides a context. SystemUIFactory @Provide dependencies that need to be overridden by SystemUI -variants (like other form factors). DependencyProvider provides or binds any +variants (like other form factors). DependencyBinder creates the mapping from +interfaces to implementation classes. DependencyProvider provides or binds any remaining depedencies required. ### Adding injection to a new SystemUI object @@ -195,10 +198,5 @@ public CustomView(@Named(VIEW_CONTEXT) Context themedViewContext, AttributeSet a ## TODO List - - Eliminate usages of Depndency#get - - Add support for Fragments to handle injection automatically - - (this could be through dagger2-android or something custom) - - Reduce number of things with @Provide in DependencyProvider (many can be - @Inject instead) - - Migrate as many remaining DependencyProvider instances to @Bind + - Eliminate usages of Dependency#get - Add links in above TODO diff --git a/packages/SystemUI/legacy/recents/res/drawable/ic_lock_to_app_24dp.xml b/packages/SystemUI/legacy/recents/res/drawable/ic_lock_to_app_24dp.xml deleted file mode 100644 index 2d779499f6e6..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/ic_lock_to_app_24dp.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="@color/recents_task_view_lock_to_app_button_color" - android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/> -</vector> diff --git a/packages/SystemUI/legacy/recents/res/drawable/recents_freeform_workspace_bg.xml b/packages/SystemUI/legacy/recents/res/drawable/recents_freeform_workspace_bg.xml deleted file mode 100644 index 5f9341c0d151..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/recents_freeform_workspace_bg.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 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. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners android:topLeftRadius="@dimen/recents_task_view_rounded_corners_radius" - android:topRightRadius="@dimen/recents_task_view_rounded_corners_radius"/> - <solid android:color="#00000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_dark.xml b/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_dark.xml deleted file mode 100644 index 9a060b4a3d39..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_dark.xml +++ /dev/null @@ -1,42 +0,0 @@ -<!-- -Copyright (C) 2015 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:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <group - android:translateX="-286.000000" - android:translateY="-602.000000"> - <group - android:translateX="109.000000" - android:translateY="514.000000"> - <group - android:translateX="178.000000" - android:translateY="89.000000"> - <path - android:strokeColor="@color/recents_task_bar_dark_icon_color" - android:strokeWidth="2" - android:pathData="M10,12 L10,3 L19,3 L19,5 L19,11 L19,12 L10,12 Z" /> - <path - android:strokeColor="@color/recents_task_bar_dark_icon_color" - android:strokeWidth="2" - android:pathData="M15,17 L5,17 L5,7 L5,17 Z" /> - </group> - </group> - </group> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_light.xml b/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_light.xml deleted file mode 100644 index b8acedb3c2f7..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_light.xml +++ /dev/null @@ -1,42 +0,0 @@ -<!-- -Copyright (C) 2015 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:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <group - android:translateX="-286.000000" - android:translateY="-602.000000"> - <group - android:translateX="109.000000" - android:translateY="514.000000"> - <group - android:translateX="178.000000" - android:translateY="89.000000"> - <path - android:strokeColor="@color/recents_task_bar_light_icon_color" - android:strokeWidth="2" - android:pathData="M10,12 L10,3 L19,3 L19,5 L19,11 L19,12 L10,12 Z" /> - <path - android:strokeColor="@color/recents_task_bar_light_icon_color" - android:strokeWidth="2" - android:pathData="M15,17 L5,17 L5,7 L5,17 Z" /> - </group> - </group> - </group> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DarkIconDispatcher.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java index 0823db9aa7a9..c7bc858c8266 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DarkIconDispatcher.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java @@ -1,62 +1,80 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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 + * 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. + * 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; +package com.android.systemui.plugins; import android.graphics.Color; import android.graphics.Rect; import android.view.View; import android.widget.ImageView; -import com.android.systemui.Dumpable; -import com.android.systemui.statusbar.phone.LightBarTransitionsController; - -import java.io.FileDescriptor; -import java.io.PrintWriter; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.plugins.annotations.DependsOn; +import com.android.systemui.plugins.annotations.ProvidesInterface; /** * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area and dark - * intensity + * intensity. Accessible through {@link PluginDependency} */ -public interface DarkIconDispatcher extends Dumpable { +@ProvidesInterface(version = DarkIconDispatcher.VERSION) +@DependsOn(target = DarkReceiver.class) +public interface DarkIconDispatcher { + int VERSION = 1; + /** + * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. + * + * @param r the area in which icons should change its tint, in logical screen + * coordinates + */ void setIconsDarkArea(Rect r); - LightBarTransitionsController getTransitionsController(); + /** + * Adds a receiver to receive callbacks onDarkChanged + */ void addDarkReceiver(DarkReceiver receiver); + + /** + * Adds a receiver to receive callbacks onDarkChanged + */ void addDarkReceiver(ImageView imageView); - // Must have been previously been added through one of the addDarkReceive methods above. + /** + * Must have been previously been added through one of the addDarkReceive methods above. + */ void removeDarkReceiver(DarkReceiver object); - void removeDarkReceiver(ImageView object); - - // Used to reapply darkness on an object, must have previously been added through - // addDarkReceiver. - void applyDark(DarkReceiver object); /** - * Dumpable interface + * Must have been previously been added through one of the addDarkReceive methods above. */ - default void dump(FileDescriptor fd, PrintWriter pw, String[] args) {} + void removeDarkReceiver(ImageView object); + + /** + * Used to reapply darkness on an object, must have previously been added through + * addDarkReceiver. + */ + void applyDark(DarkReceiver object); int DEFAULT_ICON_TINT = Color.WHITE; Rect sTmpRect = new Rect(); int[] sTmpInt2 = new int[2]; /** - * @return the tint to apply to {@param view} depending on the desired tint {@param color} and - * the screen {@param tintArea} in which to apply that tint + * @return the tint to apply to view depending on the desired tint color and + * the screen tintArea in which to apply that tint */ static int getTint(Rect tintArea, View view, int color) { if (isInArea(tintArea, view)) { @@ -67,8 +85,8 @@ public interface DarkIconDispatcher extends Dumpable { } /** - * @return the dark intensity to apply to {@param view} depending on the desired dark - * {@param intensity} and the screen {@param tintArea} in which to apply that intensity + * @return the dark intensity to apply to view depending on the desired dark + * intensity and the screen tintArea in which to apply that intensity */ static float getDarkIntensity(Rect tintArea, View view, float intensity) { if (isInArea(tintArea, view)) { @@ -79,7 +97,7 @@ public interface DarkIconDispatcher extends Dumpable { } /** - * @return true if more than half of the {@param view} area are in {@param area}, false + * @return true if more than half of the view area are in area, false * otherwise */ static boolean isInArea(Rect area, View view) { @@ -99,7 +117,12 @@ public interface DarkIconDispatcher extends Dumpable { return majorityOfWidth && coversFullStatusBar; } + /** + * Receives a callback on darkness changes + */ + @ProvidesInterface(version = DarkReceiver.VERSION) interface DarkReceiver { + int VERSION = 1; void onDarkChanged(Rect area, float darkIntensity, int tint); } } diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml index 89c468dc58a8..258219abae5f 100644 --- a/packages/SystemUI/res-keyguard/values-as/strings.xml +++ b/packages/SystemUI/res-keyguard/values-as/strings.xml @@ -71,7 +71,7 @@ <string name="kg_pattern_instructions" msgid="5547646893001491340">"আপোনাৰ আৰ্হি আঁকক"</string> <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ছিমৰ পিন দিয়ক।"</string> <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"ৰ ছিমৰ পিন দিয়ক।"</string> - <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> ম\'বাইল সেৱা অবিহনে ডিভাইচ ব্যৱহাৰ কৰিবলৈ ই-ছিম অক্ষম কৰক।"</string> + <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> ম’বাইল সেৱা অবিহনে ডিভাইচ ব্যৱহাৰ কৰিবলৈ ই-ছিম অক্ষম কৰক।"</string> <string name="kg_pin_instructions" msgid="4069609316644030034">"পিন দিয়ক"</string> <string name="kg_password_instructions" msgid="136952397352976538">"পাছৱৰ্ড দিয়ক"</string> <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ছিমখন বর্তমান অক্ষম অৱস্থাত আছে। অব্যাহত ৰাখিবলৈ PUK ক\'ড লিখক। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।"</string> @@ -113,7 +113,7 @@ </plurals> <string name="kg_password_pin_failed" msgid="8769990811451236223">"ছিম পিনৰ জৰিয়তে আনলক কৰিব পৰা নগ\'ল!"</string> <string name="kg_password_puk_failed" msgid="1331621440873439974">"ছিম PUKৰ জৰিয়তে আনলক কৰিব পৰা নগ\'ল!"</string> - <string name="kg_pin_accepted" msgid="7637293533973802143">"ক\'ড গ্ৰহণ কৰা হ\'ল!"</string> + <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> @@ -147,7 +147,7 @@ <item quantity="other">ছিমৰ পিন দিয়ক। আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g>বাৰ প্ৰয়াস কৰিব পাৰে।</item> </plurals> <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352"> - <item quantity="one">ছিমখন অক্ষম হ\'ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item> - <item quantity="other">ছিমখন অক্ষম হ\'ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item> + <item quantity="one">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item> + <item quantity="other">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item> </plurals> </resources> diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml index 041e9904e0e9..c21faead879d 100644 --- a/packages/SystemUI/res-keyguard/values-ne/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml @@ -28,8 +28,8 @@ <string name="keyguard_password_entry_touch_hint" msgid="5790410752696806482"><font size="17">"पासवर्ड टाइप गर्न छुनुहोस्"</font></string> <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"अनलक गर्न पासवर्ड टाइप गर्नुहोस्"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string> - <string name="keyguard_enter_your_pin" msgid="7152989016739952871">"आफ्नो PIN प्रविष्ट गर्नुहोस्"</string> - <string name="keyguard_enter_your_pattern" msgid="4297890206109830353">"आफ्नो ढाँचा प्रविष्ट गर्नुहोस्"</string> + <string name="keyguard_enter_your_pin" msgid="7152989016739952871">"आफ्नो PIN प्रविष्टि गर्नुहोस्"</string> + <string name="keyguard_enter_your_pattern" msgid="4297890206109830353">"आफ्नो ढाँचा प्रविष्टि गर्नुहोस्"</string> <string name="keyguard_enter_your_password" msgid="5397328359341314506">"आफ्नो पासवर्ड प्रविष्ट गर्नु…"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN कोड गलत छ।"</string> <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"अमान्य कार्ड।"</string> @@ -70,18 +70,18 @@ </plurals> <string name="kg_pattern_instructions" msgid="5547646893001491340">"आफ्नो ढाँचा कोर्नुहोस्"</string> <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM को PIN प्रविष्टि गर्नुहोस्।"</string> - <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" को SIM को PIN प्रविष्ट गर्नुहोस्।"</string> + <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" को SIM को PIN प्रविष्टि गर्नुहोस्।"</string> <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> मोबाइल सेवा बिना यन्त्रको प्रयोग गर्न eSIM लाई असक्षम पार्नुहोस्।"</string> <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN प्रविष्टि गर्नुहोस्"</string> - <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड प्रविष्ट गर्नुहोस्"</string> - <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्ट गर्नुहोस्। विवरणको लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string> - <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"SIM <xliff:g id="CARRIER">%1$s</xliff:g> अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्ट गर्नुहोस्। विवरणका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string> + <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड प्रविष्टि गर्नुहोस्"</string> + <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्टि गर्नुहोस्। विवरणको लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string> + <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"SIM <xliff:g id="CARRIER">%1$s</xliff:g> अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्टि गर्नुहोस्। विवरणका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string> <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"रूचाइएको PIN कोड प्रविष्टि गर्नुहोस्"</string> <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"रूचाइएको PIN कोड पुष्टि गर्नुहोस्"</string> <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"SIM कार्ड अनलक गरिँदै..."</string> <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"४ देखि ८ वटा नम्बर भएको एउटा PIN टाइप गर्नुहोस्।"</string> <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"PUK कोड ८ वा सो भन्दा बढी नम्बरको हुनु पर्छ।"</string> - <string name="kg_invalid_puk" msgid="5399287873762592502">"PUK कोड पुन: प्रविष्ट गर्नुहोस्। पटक-पटकको प्रयासले SIM सदाका लागि असक्षम हुनेछ।"</string> + <string name="kg_invalid_puk" msgid="5399287873762592502">"PUK कोड पुन: प्रविष्टि गर्नुहोस्। पटक-पटकको प्रयासले SIM सदाका लागि असक्षम हुनेछ।"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"PIN कोडहरू मिलेनन्"</string> <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"अत्यन्त धेरै ढाँचा कोर्ने प्रयासहरू"</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो PIN प्रविष्ट गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string> @@ -143,11 +143,11 @@ <string name="kg_fingerprint_not_recognized" msgid="7854413849848459418">"पहिचान भएन"</string> <string name="kg_face_not_recognized" msgid="6382535088345875294">"पहिचान भएन"</string> <plurals name="kg_password_default_pin_message" formatted="false" msgid="3739658416797652781"> - <item quantity="other">SIM को PIN प्रविष्ट गर्नुहोस्। तपाईंसँग <xliff:g id="NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्।</item> - <item quantity="one">SIM को PIN प्रविष्ट गर्नुहोस्। तपाईंसँग <xliff:g id="NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि भने आफ्नो यन्त्र अनलक गर्नका लागि तपाईंले अनिवार्य रूपमा आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नु पर्ने हुन्छ।</item> + <item quantity="other">SIM को PIN प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्।</item> + <item quantity="one">SIM को PIN प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि भने आफ्नो यन्त्र अनलक गर्नका लागि तपाईंले अनिवार्य रूपमा आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नु पर्ने हुन्छ।</item> </plurals> <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352"> - <item quantity="other">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्ट गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item> - <item quantity="one">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्ट गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item> + <item quantity="other">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item> + <item quantity="one">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item> </plurals> </resources> diff --git a/packages/SystemUI/res/drawable-hdpi/ic_cancel_white_24dp.png b/packages/SystemUI/res/drawable-hdpi/ic_cancel_white_24dp.png Binary files differdeleted file mode 100644 index 73f5116bd71f..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_cancel_white_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_dismiss_outline.png b/packages/SystemUI/res/drawable-hdpi/ic_dismiss_outline.png Binary files differdeleted file mode 100755 index 9afd8fa14d31..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_dismiss_outline.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 552a3d1ff43a..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-land/search_panel_scrim.xml b/packages/SystemUI/res/drawable-land/search_panel_scrim.xml deleted file mode 100644 index 102cc9c16a9e..000000000000 --- a/packages/SystemUI/res/drawable-land/search_panel_scrim.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - ~ Copyright (C) 2014 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 - --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <gradient - android:type="linear" - android:angle="180" - android:startColor="#55000000" - android:endColor="#00000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable-mdpi/ic_cancel_white_24dp.png b/packages/SystemUI/res/drawable-mdpi/ic_cancel_white_24dp.png Binary files differdeleted file mode 100644 index 787e2593789b..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_cancel_white_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_dismiss_outline.png b/packages/SystemUI/res/drawable-mdpi/ic_dismiss_outline.png Binary files differdeleted file mode 100755 index 35737aa704ea..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_dismiss_outline.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 48b96d810a0a..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-nodpi/scorecard_gameover.xml b/packages/SystemUI/res/drawable-nodpi/scorecard_gameover.xml deleted file mode 100644 index f663a661f3f1..000000000000 --- a/packages/SystemUI/res/drawable-nodpi/scorecard_gameover.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" - > - <corners - android:radius="8dp" /> - <solid - android:color="#ffff0000" /> -</shape> diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 23ec6dbde642..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index e4500587e5b5..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index d18e41906f57..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 00a751cfe3a4..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml b/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml deleted file mode 100644 index bbb2617db4a0..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - ~ Copyright (C) 2014 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 - --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <gradient - android:type="linear" - android:angle="90" - android:startColor="#55000000" - android:endColor="#00000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_light_old.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_light_old.png Binary files differdeleted file mode 100644 index b336ccd2b5a1..000000000000 --- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_light_old.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_cancel_white_24dp.png b/packages/SystemUI/res/drawable-xhdpi/ic_cancel_white_24dp.png Binary files differdeleted file mode 100644 index 6ebbc831605f..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_cancel_white_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_dismiss_outline.png b/packages/SystemUI/res/drawable-xhdpi/ic_dismiss_outline.png Binary files differdeleted file mode 100755 index f1bfa891d229..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_dismiss_outline.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index e49db340dcfe..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index b91704a928ab..000000000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable/dismiss_all_shape.xml b/packages/SystemUI/res/drawable/dismiss_all_shape.xml deleted file mode 100644 index fb371c6beb07..000000000000 --- a/packages/SystemUI/res/drawable/dismiss_all_shape.xml +++ /dev/null @@ -1,39 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="17dp" - android:width="85dp" - android:viewportHeight="48" - android:viewportWidth="260" > - <group - android:name="dismiss_all" - android:translateX="48" - android:translateY="6" > - <group - android:name="3" - android:translateX="-24" - android:translateY="36" > - <path - android:name="rectangle_path_1_2" - android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - <group - android:name="2" - android:translateX="-12" - android:translateY="18" > - <path - android:name="rectangle_path_1_1" - android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - <group - android:name="1" > - <path - android:name="rectangle_path_1" - android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/fingerprint_icon.xml b/packages/SystemUI/res/drawable/fingerprint_icon.xml deleted file mode 100644 index 76a86ae42da2..000000000000 --- a/packages/SystemUI/res/drawable/fingerprint_icon.xml +++ /dev/null @@ -1,107 +0,0 @@ -<?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 - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="60dp" - android:height="60dp" - android:viewportWidth="60" - android:viewportHeight="60"> - - <path - android:fillColor="#1A73E8" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M 30 0 C 46.5685424949 0 60 13.4314575051 60 30 C 60 46.5685424949 46.5685424949 60 30 60 C 13.4314575051 60 0 46.5685424949 0 30 C 0 13.4314575051 13.4314575051 0 30 0 Z" /> - <group - android:translateX="17.727273" - android:translateY="16.363636"> - <path - android:fillColor="#FFFFFF" - android:strokeWidth="1" - android:pathData="M20.3065726,3.44516129 C20.1974817,3.44516129 20.0883908,3.41788856 -19.9929362,3.36334311 C17.3747544,2.01334311 15.111118,1.44061584 -12.3974817,1.44061584 C9.69748166,1.44061584 7.1338453,2.08152493 -4.80202711,3.36334311 C4.47475439,3.54061584 4.06566348,3.41788856 -3.87475439,3.09061584 C3.69748166,2.76334311 3.82020893,2.34061584 -4.14748166,2.16334311 C6.6838453,0.786070381 9.46566348,0.0769794721 -12.3974817,0.0769794721 C15.3020271,0.0769794721 17.8383908,0.717888563 -20.6202089,2.14970674 C20.961118,2.32697947 21.0838453,2.73607038 -20.9065726,3.06334311 C20.7838453,3.30879765 20.5520271,3.44516129 -20.3065726,3.44516129 L20.3065726,3.44516129 Z M0.792936205,10.6042522 -C0.656572568,10.6042522 0.520208932,10.5633431 0.397481659,10.4815249 -C0.0838452956,10.2633431 0.0156634774,9.84061584 0.233845296,9.52697947 -C1.5838453,7.61788856 3.30202711,6.11788856 5.34748166,5.06788856 -C9.62929984,2.85879765 15.111118,2.84516129 19.4065726,5.0542522 -C21.4520271,6.1042522 23.1702089,7.59061584 24.5202089,9.48607038 -C24.7383908,9.78607038 24.6702089,10.222434 24.3565726,10.4406158 -C24.0429362,10.6587977 23.6202089,10.5906158 23.4020271,10.2769795 -C22.1747544,8.55879765 20.6202089,7.20879765 18.7792998,6.26788856 -C14.8656635,4.26334311 9.86111802,4.26334311 5.96111802,6.28152493 -C4.10657257,7.23607038 2.55202711,8.59970674 1.32475439,10.3178886 -C1.21566348,10.5087977 1.01111802,10.6042522 0.792936205,10.6042522 -L0.792936205,10.6042522 Z M9.31566348,27.0633431 C9.13839075,27.0633431 -8.96111802,26.9951613 8.83839075,26.8587977 C7.65202711,25.672434 -7.01111802,24.9087977 6.09748166,23.2587977 C5.15657257,21.5815249 -4.66566348,19.5360704 4.66566348,17.3406158 C4.66566348,13.2906158 -8.12929984,9.99061584 12.3838453,9.99061584 C16.6383908,9.99061584 -20.1020271,13.2906158 20.1020271,17.3406158 C20.1020271,17.722434 -19.8020271,18.022434 19.4202089,18.022434 C19.0383908,18.022434 -18.7383908,17.722434 18.7383908,17.3406158 C18.7383908,14.0406158 -15.8883908,11.3542522 12.3838453,11.3542522 C8.87929984,11.3542522 -6.02929984,14.0406158 6.02929984,17.3406158 C6.02929984,19.3042522 -6.46566348,21.1178886 7.29748166,22.5906158 C8.17020893,24.1587977 -8.77020893,24.8269795 9.82020893,25.8906158 C10.0792998,26.1633431 -10.0792998,26.5860704 9.82020893,26.8587977 C9.67020893,26.9951613 -9.4929362,27.0633431 9.31566348,27.0633431 Z M19.0929362,24.5406158 -C17.4702089,24.5406158 16.0383908,24.1315249 14.8656635,23.3269795 -C12.8338453,21.9497067 11.6202089,19.7133431 11.6202089,17.3406158 -C11.6202089,16.9587977 11.9202089,16.6587977 12.3020271,16.6587977 -C12.6838453,16.6587977 12.9838453,16.9587977 12.9838453,17.3406158 -C12.9838453,19.2633431 13.9656635,21.0769795 15.6292998,22.1951613 -C16.5974817,22.8497067 17.7292998,23.1633431 19.0929362,23.1633431 -C19.4202089,23.1633431 19.9656635,23.122434 20.511118,23.0269795 -C20.8792998,22.9587977 21.2338453,23.2042522 21.3020271,23.5860704 -C21.3702089,23.9542522 21.1247544,24.3087977 20.7429362,24.3769795 -C19.9656635,24.5269795 19.2838453,24.5406158 19.0929362,24.5406158 -L19.0929362,24.5406158 Z M16.3520271,27.3497067 C16.2974817,27.3497067 -16.2292998,27.3360704 16.1747544,27.322434 C14.0065726,26.722434 -12.5883908,25.9178886 11.1020271,24.4587977 C9.1929362,22.5633431 -8.1429362,20.0406158 8.1429362,17.3406158 C8.1429362,15.1315249 -10.0247544,13.3315249 12.3429362,13.3315249 C14.661118,13.3315249 -16.5429362,15.1315249 16.5429362,17.3406158 C16.5429362,18.7997067 -17.811118,19.9860704 19.3792998,19.9860704 C20.9474817,19.9860704 -22.2156635,18.7997067 22.2156635,17.3406158 C22.2156635,12.1997067 -17.7838453,8.02697947 12.3292998,8.02697947 C8.45657257,8.02697947 -4.91111802,10.1815249 3.31566348,13.522434 C2.7838453,14.6269795 -2.51111802,15.922434 2.51111802,17.3406158 C2.51111802,18.4042522 -2.60657257,20.0815249 3.42475439,22.2633431 C3.56111802,22.6178886 -3.3838453,23.0133431 3.02929984,23.1360704 C2.67475439,23.272434 -2.27929984,23.0815249 2.15657257,22.7406158 C1.48839075,20.9542522 -1.16111802,19.1815249 1.16111802,17.3406158 C1.16111802,15.7042522 -1.47475439,14.2178886 2.08839075,12.922434 C3.90202711,9.11788856 -7.92475439,6.64970674 12.3292998,6.64970674 C18.5338453,6.64970674 -23.5792998,11.4360704 23.5792998,17.3269795 C23.5792998,19.5360704 -21.6974817,21.3360704 19.3792998,21.3360704 C17.061118,21.3360704 -15.1792998,19.5360704 15.1792998,17.3269795 C15.1792998,15.8678886 -13.911118,14.6815249 12.3429362,14.6815249 C10.7747544,14.6815249 -9.50657257,15.8678886 9.50657257,17.3269795 C9.50657257,19.6587977 -10.4065726,21.8406158 12.0565726,23.4769795 C13.3520271,24.7587977 -14.5929362,25.4678886 16.5156635,25.9997067 C16.8838453,26.0951613 -17.0883908,26.4769795 16.9929362,26.8315249 C16.9247544,27.1451613 -16.6383908,27.3497067 16.3520271,27.3497067 L16.3520271,27.3497067 Z" /> - </group> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/header_dot.xml b/packages/SystemUI/res/drawable/header_dot.xml deleted file mode 100644 index dbc6b378bd63..000000000000 --- a/packages/SystemUI/res/drawable/header_dot.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** Copyright 2015, 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. ---> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="oval" - android:tint="?android:attr/colorControlNormal"> - - <solid - android:color="#FFFFFF"/> - - <size - android:width="3dp" - android:height="3dp"/> -</shape> diff --git a/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml b/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml deleted file mode 100644 index 6134b8f75457..000000000000 --- a/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M11.0,22.98l0.0,-8.98 -4.0,0.0 6.0,-13.0 0.0,9.0 4.0,0.0z" - android:fillColor="#ffffff"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_cast.xml b/packages/SystemUI/res/drawable/ic_cast.xml deleted file mode 100644 index b86dfea07682..000000000000 --- a/packages/SystemUI/res/drawable/ic_cast.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M1 18v2c0 .55 .45 1 1 1h2c0-1.66-1.34-3-3-3zm0-2.94c-.01 .51 .32 .93 .82 1.02 -2.08 .36 3.74 2 4.1 4.08 .09 .48 .5 .84 .99 .84 .61 0 1.09-.54 1-1.14a6.996 -6.996 0 0 0-5.8-5.78c-.59-.09-1.09 .38 -1.11 .98 zm0-4.03c-.01 .52 .34 .96 .85 -1.01 4.26 .43 7.68 3.82 8.1 8.08 .05 .5 .48 .88 .99 .88 .59 0 1.06-.51 -1-1.1-.52-5.21-4.66-9.34-9.87-9.85-.57-.05-1.05 .4 -1.07 .98 zM21 3H3c-1.1 0-2 -.9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_chevron_left.xml b/packages/SystemUI/res/drawable/ic_chevron_left.xml deleted file mode 100644 index 379382b06504..000000000000 --- a/packages/SystemUI/res/drawable/ic_chevron_left.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- - ~ Copyright (C) 2014 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:width="24dp" - android:height="24dp" - android:viewportWidth="36.0" - android:viewportHeight="36.0"> - - <path - android:fillColor="#ffffffff" - android:pathData="M23.1,11.1l-2.1000004,-2.1000004 -9.0,9.0 9.0,9.0 2.1000004,-2.1000004 -6.8999996,-6.8999996z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_off.xml b/packages/SystemUI/res/drawable/ic_data_off.xml deleted file mode 100644 index b97ddaef6418..000000000000 --- a/packages/SystemUI/res/drawable/ic_data_off.xml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M21.6,21.6L10.8,10.9L2.1,2.1L0.8,3.4l3.3,3.3C3.1,8.2 2.5,10.0 2.5,12.0c0.0,5.2 4.3,9.5 9.5,9.5c2.0,0.0 3.8,-0.6 5.3,-1.6l3.0,3.0L21.6,21.6zM9.6,12.2l0.7,0.7L9.6,12.9L9.6,12.2zM13.9,18.6c-0.2,0.2 -0.5,0.2 -0.6,0.0l-2.4,-3.7l1.5,0.0l2.4,2.4L13.9,18.6z" - android:fillColor="#ffffff"/> - <path - android:pathData="M12.0,2.5c-2.0,0.0 -3.8,0.6 -5.3,1.6l2.5,2.5L10.0,5.4c0.2,-0.2 0.5,-0.2 0.6,0.0L13.0,9.1l-1.4,0.0l2.0,2.0l0.6,0.0l0.0,0.6l5.6,5.6c1.0,-1.5 1.6,-3.3 1.6,-5.3C21.5,6.8 17.2,2.5 12.0,2.5z" - android:fillColor="#ffffff"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_on.xml b/packages/SystemUI/res/drawable/ic_data_on.xml deleted file mode 100644 index a65dc7922ceb..000000000000 --- a/packages/SystemUI/res/drawable/ic_data_on.xml +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12.0,12.0m-9.5,0.0a9.5,9.5 0.0,1.0 1.0,19.0 0.0a9.5,9.5 0.0,1.0 1.0,-19.0 0.0 - M10.6,5.4c-0.2,-0.2 -0.5,-0.2 -0.6,0.0L7.6,9.1l2.0,0.0l0.0,3.8L11.0,12.900001L11.0,9.1l2.0,0.0L10.6,5.4z - M13.3,18.6c0.2,0.2 0.5,0.2 0.6,0.0l2.4,-3.7l-2.0,0.0l0.0,-3.8l-1.4,0.0l0.0,3.8l-2.0,0.0L13.3,18.6z" - android:fillColor="#ffffff"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_unavailable.xml b/packages/SystemUI/res/drawable/ic_data_unavailable.xml deleted file mode 100644 index ffb2af71c546..000000000000 --- a/packages/SystemUI/res/drawable/ic_data_unavailable.xml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M15.8,12.9l3.7,0.0c0.0,-0.3 0.0,-0.6 0.0,-0.9c0.0,-5.2 -4.3,-9.5 -9.5,-9.5S0.6,6.8 0.6,12.0s4.3,9.5 9.5,9.5c2.1,0.0 4.1,-0.7 5.7,-1.9L15.8,12.9zM5.7,9.1l2.4,-3.7c0.2,-0.2 0.5,-0.2 0.6,0.0l2.4,3.7l-2.0,0.0l0.0,3.8L7.8,12.900001L7.8,9.1L5.7,9.1zM11.4,18.6L9.0,14.9l2.0,0.0l0.0,-3.8l1.4,0.0l0.0,3.8l2.0,0.0L12.0,18.6C11.9,18.8 11.6,18.8 11.4,18.6z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M23.4,19.4l-2.1,-2.1 2.1,-2.199999 -1.1,-1.0 -2.099998,2.1 -2.1,-2.1 -1.1,1.099999 2.1,2.099999 -2.1,2.1 1.1,1.1 2.1,-2.200001 2.099998,2.200001z" - android:fillColor="#FFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_expand_less.xml b/packages/SystemUI/res/drawable/ic_expand_less.xml deleted file mode 100644 index e96801353ffa..000000000000 --- a/packages/SystemUI/res/drawable/ic_expand_less.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2015 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:width="20.0dp" - android:height="20.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12.000000,8.000000l-6.000000,6.000000 1.400000,1.400000 4.600000,-4.599999 4.600000,4.599999 1.400000,-1.400000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_expand_more.xml b/packages/SystemUI/res/drawable/ic_expand_more.xml deleted file mode 100644 index 72e98ec21897..000000000000 --- a/packages/SystemUI/res/drawable/ic_expand_more.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2015 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:width="20.0dp" - android:height="20.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_history.xml b/packages/SystemUI/res/drawable/ic_history.xml deleted file mode 100644 index e936864f82ab..000000000000 --- a/packages/SystemUI/res/drawable/ic_history.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:fillColor="#FFFFFF" - android:pathData="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89 .07 .14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 -7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 -21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54 .72 -1.21-3.5-2.08V8H12z" /> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_home_button_outline.xml b/packages/SystemUI/res/drawable/ic_home_button_outline.xml deleted file mode 100644 index 5bf345d4f73b..000000000000 --- a/packages/SystemUI/res/drawable/ic_home_button_outline.xml +++ /dev/null @@ -1,25 +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 xmlns:android="http://schemas.android.com/apk/res/android" - android:width="28dp" - android:height="10dp" - android:viewportWidth="28" - android:viewportHeight="10"> - <path - android:pathData="M23,1H5C2.7909,1 1,2.7909 1,5C1,7.2091 2.7909,9 5,9H23C25.2091,9 27,7.2091 27,5C27,2.7909 25.2091,1 23,1ZM5,0C2.2386,0 0,2.2386 0,5C0,7.7614 2.2386,10 5,10H23C25.7614,10 28,7.7614 28,5C28,2.2386 25.7614,0 23,0H5Z" - android:fillColor="?attr/wallpaperTextColor" - android:fillType="evenOdd"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_back.xml b/packages/SystemUI/res/drawable/ic_qs_back.xml deleted file mode 100644 index f00ba03eb829..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_back.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M20.0,11.0L7.8,11.0l5.6,-5.6L12.0,4.0l-8.0,8.0l8.0,8.0l1.4,-1.4L7.8,13.0L20.0,13.0L20.0,11.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_battery_saver.xml b/packages/SystemUI/res/drawable/ic_qs_battery_saver.xml deleted file mode 100644 index 7b29740be338..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_battery_saver.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - Copyright (C) 2016 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:autoMirrored="true" - android:width="32.0dp" - android:height="32.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal"> - <path - android:pathData="M5,3 - l3.5,0 l0,-1.5 l7,0 l0,1.5 l3.5,0 l0,19.5 l-14,0z - M10.5,8.5 l0,3 l-3,0 l0,3 l3,0 l0,3 l3,0 l0,-3 l3,0 l0,-3 l-3,0 l0,-3 z" - android:fillColor="#FFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_lock.xml b/packages/SystemUI/res/drawable/ic_qs_lock.xml deleted file mode 100644 index 204af7e81f4c..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_lock.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="@color/keyguard_affordance" - android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_lock_open.xml b/packages/SystemUI/res/drawable/ic_qs_lock_open.xml deleted file mode 100644 index c877f063b7a8..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_lock_open.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="@color/keyguard_affordance" - android:pathData="M12.0,17.0c1.1,0.0 2.0,-0.9 2.0,-2.0s-0.9,-2.0 -2.0,-2.0c-1.1,0.0 -2.0,0.9 -2.0,2.0S10.9,17.0 12.0,17.0zM18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l1.9,0.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM18.0,20.0L6.0,20.0L6.0,10.0l12.0,0.0L18.0,20.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_network_logging.xml b/packages/SystemUI/res/drawable/ic_qs_network_logging.xml deleted file mode 100644 index 7bdf50c74bed..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_network_logging.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -Copyright (C) 2016 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. ---> - -<!-- Placeholder icon for network logging until the real icon is finalized--> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="12.0dp" - android:height="12.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M2,24v-4h12v4H2z M2,16v-4h20v4H2z M5,7 12,0 19,7 14,7 14,15 10,15 10,7z"/> - -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml deleted file mode 100644 index 29741577c039..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml deleted file mode 100644 index 6db508cd31e8..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M16,16L2.81,2.81L1.39,4.22l4.85,4.85C6.09,9.68 6,10.33 6,11v6H4v2h12.17l3.61,3.61l1.41,-1.41L16,16zM8,17c0,0 0.01,-6.11 0.01,-6.16L14.17,17H8z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,6.5c2.49,0 4,2.02 4,4.5v2.17l2,2V11c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.72,4.86 9.05,5.2 8.46,5.63L9.93,7.1C10.51,6.73 11.2,6.5 12,6.5z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml deleted file mode 100644 index c87b595a20f2..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml deleted file mode 100644 index 4a2bd548f61d..000000000000 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<animated-vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:drawable="@drawable/ic_signal_workmode_disable" > - <target - android:name="mask_1" - android:animation="@anim/ic_signal_workmode_disable_mask_1_animation" /> - <target - android:name="whole" - android:animation="@anim/ic_signal_workmode_disable_whole_animation" /> - <target - android:name="rectangle_path_3_position" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_position_animation" /> - <target - android:name="rectangle_path_3" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_animation" /> - <target - android:name="rectangle_path_4_position" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_position_animation" /> - <target - android:name="rectangle_path_4" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_animation" /> - <target - android:name="left" - android:animation="@anim/ic_signal_workmode_disable_left_animation" /> - <target - android:name="right" - android:animation="@anim/ic_signal_workmode_disable_right_animation" /> - <target - android:name="stick" - android:animation="@anim/ic_signal_workmode_disable_stick_animation" /> - <target - android:name="ic_signal_workmode_disable" - android:animation="@anim/ic_signal_workmode_disable_stickito_animation" /> -</animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml deleted file mode 100644 index 2d4f0b5d162f..000000000000 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml +++ /dev/null @@ -1,128 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:name="ic_signal_workmode_enable" - android:width="42dp" - android:viewportWidth="42" - android:height="42dp" - android:viewportHeight="42" > - <group - android:name="suitcase" - android:translateX="21" - android:translateY="36.9375" - android:scaleX="0.1" - android:scaleY="0.1" > - <group - android:name="suitcase_pivot" - android:translateY="-158" > - <clip-path - android:name="mask_1" - android:pathData="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" /> - <group - android:name="whole" - android:translateX="-1.11523" - android:translateY="32.0918" - android:scaleX="0" - android:scaleY="0" > - <path - android:name="rectangle_path_1" - android:strokeColor="#FFFFFFFF" - android:strokeWidth="65" - android:pathData="M 0.0,-66.5 l 0.0,0.0 c 36.7269358617,0.0 66.5,29.7730641383 66.5,66.5 l 0.0,0.0 c 0.0,36.7269358617 -29.7730641383,66.5 -66.5,66.5 l 0.0,0.0 c -36.7269358617,0.0 -66.5,-29.7730641383 -66.5,-66.5 l 0.0,0.0 c 0.0,-36.7269358617 29.7730641383,-66.5 66.5,-66.5 Z" /> - </group> - <group - android:name="handle" - android:translateY="-100" > - <path - android:name="rectangle_path_2" - android:strokeColor="#FFFFFFFF" - android:strokeWidth="35" - android:pathData="M -34.0,-50.0 l 68.0,0.0 c 8.8365559968,0.0 16.0,7.1634440032 16.0,16.0 l 0.0,68.0 c 0.0,8.8365559968 -7.1634440032,16.0 -16.0,16.0 l -68.0,0.0 c -8.8365559968,0.0 -16.0,-7.1634440032 -16.0,-16.0 l 0.0,-68.0 c 0.0,-8.8365559968 7.1634440032,-16.0 16.0,-16.0 Z" /> - </group> - <group - android:name="case" - android:translateY="32.68518" > - <group - android:name="case_pivot" - android:translateY="-32.68518" > - <group - android:name="bottom" - android:translateY="-97.62964" > - <group - android:name="bottom_pivot" - android:translateY="40" > - <group - android:name="rectangle_path_3_position" - android:translateY="25" > - <path - android:name="rectangle_path_3" - android:fillColor="#FFFFFFFF" - android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> - </group> - </group> - </group> - <group - android:name="top" - android:translateY="163" > - <group - android:name="top_pivot" - android:translateY="-40" > - <group - android:name="rectangle_path_4_position" - android:translateY="-25" > - <path - android:name="rectangle_path_4" - android:fillColor="#FFFFFFFF" - android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> - </group> - </group> - </group> - <group - android:name="left" - android:translateX="-175.00635" - android:translateY="30" - android:scaleX="1.8" > - <group - android:name="left_pivot" - android:translateX="50.00635" > - <path - android:name="rectangle_path_5" - android:fillColor="#FFFFFFFF" - android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> - </group> - </group> - <group - android:name="right" - android:translateX="174.97778" - android:translateY="30" - android:scaleX="1.8" > - <group - android:name="right_pivot" - android:translateX="-49.97778" > - <path - android:name="rectangle_path_6" - android:fillColor="#FFFFFFFF" - android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> - </group> - </group> - </group> - </group> - <group - android:name="stick" - android:translateX="-166.59082" - android:translateY="-156.51367" - android:rotation="-45" > - <group - android:name="stick_pivot" - android:translateX="0.18161" - android:translateY="243.8158" > - <path - android:name="stickito" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M -16.5,-243.999885 l 33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 l -33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> - </group> - </group> - </group> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml deleted file mode 100644 index c98f800d70c1..000000000000 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<animated-vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:drawable="@drawable/ic_signal_workmode_enable" > - <target - android:name="mask_1" - android:animation="@anim/ic_signal_workmode_enable_mask_1_animation" /> - <target - android:name="whole" - android:animation="@anim/ic_signal_workmode_enable_whole_animation" /> - <target - android:name="rectangle_path_3_position" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_position_animation" /> - <target - android:name="rectangle_path_3" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_animation" /> - <target - android:name="rectangle_path_4_position" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_position_animation" /> - <target - android:name="rectangle_path_4" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_animation" /> - <target - android:name="left" - android:animation="@anim/ic_signal_workmode_enable_left_animation" /> - <target - android:name="right" - android:animation="@anim/ic_signal_workmode_enable_right_animation" /> - <target - android:name="stick" - android:animation="@anim/ic_signal_workmode_enable_stick_animation" /> - <target - android:name="ic_signal_workmode_enable" - android:animation="@anim/ic_signal_workmode_enable_stickito_animation" /> -</animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_sim.xml b/packages/SystemUI/res/drawable/ic_sim.xml deleted file mode 100644 index a9a19027a8b1..000000000000 --- a/packages/SystemUI/res/drawable/ic_sim.xml +++ /dev/null @@ -1,42 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M18,2h-8L4,8v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4C20,2.9 19.1,2 18,2zM18,4v16H6V8.83L10.83,4L18,4L18,4z"/> - <path - android:fillColor="#FF000000" - android:pathData="M7,17h2v2h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M15,17h2v2h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M7,11h2v4h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M11,15h2v4h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M11,11h2v2h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M15,11h2v4h-2z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_speaker.xml b/packages/SystemUI/res/drawable/ic_speaker.xml deleted file mode 100644 index 1ea293c0b690..000000000000 --- a/packages/SystemUI/res/drawable/ic_speaker.xml +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal" > - <path - android:pathData="M17,2L7,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,1.99 2,1.99L17,22c1.1,0 2,-0.9 2,-2L19,4c0,-1.1 -0.9,-2 -2,-2zM12,4c1.1,0 2,0.9 2,2s-0.9,2 -2,2c-1.11,0 -2,-0.9 -2,-2s0.89,-2 2,-2zM12,20c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,12c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z" - android:fillColor="#FFFFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_speaker_group.xml b/packages/SystemUI/res/drawable/ic_speaker_group.xml deleted file mode 100644 index d6867d7265b0..000000000000 --- a/packages/SystemUI/res/drawable/ic_speaker_group.xml +++ /dev/null @@ -1,32 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal" > - <path - android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z" - android:fillColor="#FFFFFFFF"/> - <path - android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0" - android:fillColor="#FFFFFFFF"/> - <path - android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z" - android:fillColor="#FFFFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_swap.xml b/packages/SystemUI/res/drawable/ic_swap.xml deleted file mode 100644 index 30da2a9f532f..000000000000 --- a/packages/SystemUI/res/drawable/ic_swap.xml +++ /dev/null @@ -1,25 +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 xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorForeground"> - <path - android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z" - android:fillColor="#FFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_tv.xml b/packages/SystemUI/res/drawable/ic_tv.xml deleted file mode 100644 index cc2ae910ae88..000000000000 --- a/packages/SystemUI/res/drawable/ic_tv.xml +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal" > - <path - android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h5v2h8v-2h5c1.1,0 1.99,-0.9 1.99,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12z" - android:fillColor="#FFFFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_zen_all.xml b/packages/SystemUI/res/drawable/ic_zen_all.xml deleted file mode 100644 index 5df2447b9bb2..000000000000 --- a/packages/SystemUI/res/drawable/ic_zen_all.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="18dp" - android:height="18dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M6.6,3.6L5.2,2.2C2.8,4.0 1.2,6.8 1.0,10.0l2.0,0.0C3.2,7.3 4.5,5.0 6.6,3.6zM20.0,10.0l2.0,0.0c-0.2,-3.2 -1.7,-6.0 -4.1,-7.8l-1.4,1.4C18.5,5.0 19.8,7.3 20.0,10.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0l-2.0,-2.0L18.0,10.5zM11.5,22.0c0.1,0.0 0.3,0.0 0.4,0.0c0.7,-0.1 1.2,-0.6 1.4,-1.2c0.1,-0.2 0.2,-0.5 0.2,-0.8l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_zen_important.xml b/packages/SystemUI/res/drawable/ic_zen_important.xml deleted file mode 100644 index c2a59b85bf4a..000000000000 --- a/packages/SystemUI/res/drawable/ic_zen_important.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="18dp" - android:height="18dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12.0,17.273l6.1800003,3.7269993 -1.6350002,-7.0290003 5.455,-4.7269993 -7.191,-0.6170006 -2.809,-6.627 -2.809,6.627 -7.191,0.6170006 5.455,4.7269993 -1.6349998,7.0290003z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_zen_none.xml b/packages/SystemUI/res/drawable/ic_zen_none.xml deleted file mode 100644 index 99014f24e53f..000000000000 --- a/packages/SystemUI/res/drawable/ic_zen_none.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="18dp" - android:height="18dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M24.0,4.0C13.0,4.0 4.0,13.0 4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0c11.0,0.0 20.0,-9.0 20.0,-20.0C44.0,13.0 35.0,4.0 24.0,4.0zM24.0,40.0c-8.8,0.0 -16.0,-7.2 -16.0,-16.0c0.0,-3.7 1.3,-7.1 3.4,-9.8l22.4,22.4C31.1,38.7 27.7,40.0 24.0,40.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml b/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml deleted file mode 100644 index b812d43b3b87..000000000000 --- a/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2014 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 - --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="oval"> - <solid android:color="#1a000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/notification_expand_more.xml b/packages/SystemUI/res/drawable/notification_expand_more.xml deleted file mode 100644 index 430fb0dd523d..000000000000 --- a/packages/SystemUI/res/drawable/notification_expand_more.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright (C) 2015 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._more ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="22.0dp" - android:height="22.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pip_dismiss.xml b/packages/SystemUI/res/drawable/pip_dismiss.xml deleted file mode 100644 index f656eeb2e5ee..000000000000 --- a/packages/SystemUI/res/drawable/pip_dismiss.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2016 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:width="42.0dp" - android:height="42.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/pip_notification_icon.xml b/packages/SystemUI/res/drawable/pip_notification_icon.xml deleted file mode 100644 index 592bc60d553e..000000000000 --- a/packages/SystemUI/res/drawable/pip_notification_icon.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M11.99,18.54l-7.37,-5.73L3,14.07l9,7 9,-7 -1.63,-1.27 -7.38,5.74zM12,16l7.36,-5.73L21,9l-9,-7 -9,7 1.63,1.27L12,16z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/pop_ball.xml b/packages/SystemUI/res/drawable/pop_ball.xml deleted file mode 100644 index ee1220f42140..000000000000 --- a/packages/SystemUI/res/drawable/pop_ball.xml +++ /dev/null @@ -1,29 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M0,50 a50,50 0 1 1 100,0 - a50,50 0 1 1 -100,0" - android:fillColor="#FFFF1744"/> - <path - android:pathData="M16,36 A24,24 0 1 1 64,36 - M64,36 A24,24 0 1 1 16,36" - android:fillColor="#20FFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_belt.xml b/packages/SystemUI/res/drawable/pop_belt.xml deleted file mode 100644 index e0ea57527d2a..000000000000 --- a/packages/SystemUI/res/drawable/pop_belt.xml +++ /dev/null @@ -1,33 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-47.599998,0.000000a47.599998,47.599998 0.000000,1.000000 1.000000,95.199997 0.000000a47.599998,47.599998 0.000000,1.000000 1.000000,-95.199997 0.000000" - android:fillColor="#9C27B0"/> - <path - android:pathData="M50.000000,2.429000c-26.337999,0.000000 -47.688999,21.351000 -47.688999,47.688999c0.000000,13.168000 5.337000,25.091000 13.968000,33.722000l67.444000,-67.443001C75.092003,7.766000 63.168999,2.429000 50.000000,2.429000z" - android:fillColor="#BA68C8"/> - <path - android:pathData="M0.000000,41.573002l100.000000,0.000000l0.000000,17.090000l-100.000000,0.000000z" - android:fillColor="#9C27B0"/> - <path - android:pathData="M0.000000,58.662998l0.000000,-17.089996 100.000000,0.000000z" - android:fillColor="#BA68C8"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_droid.xml b/packages/SystemUI/res/drawable/pop_droid.xml deleted file mode 100644 index eed325c6541c..000000000000 --- a/packages/SystemUI/res/drawable/pop_droid.xml +++ /dev/null @@ -1,33 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#9E9D24"/> - <path - android:pathData="M30.775999,24.528000m-4.209000,0.000000a4.209000,4.209000 0.000000,1.000000 1.000000,8.418000 0.000000a4.209000,4.209000 0.000000,1.000000 1.000000,-8.418000 0.000000" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M69.226997,24.528000m-4.210000,0.000000a4.210000,4.210000 0.000000,1.000000 1.000000,8.420000 0.000000a4.210000,4.210000 0.000000,1.000000 1.000000,-8.420000 0.000000" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M85.352997,14.648000C65.829002,-4.877000 34.168999,-4.877000 14.646000,14.646000C4.882000,24.410000 0.002000,37.207001 0.000000,50.000999l99.996002,0.002000C99.996002,37.207001 95.115997,24.410000 85.352997,14.648000z" - android:fillColor="#C0CA33"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_pizza.xml b/packages/SystemUI/res/drawable/pop_pizza.xml deleted file mode 100644 index 1806b5a17cec..000000000000 --- a/packages/SystemUI/res/drawable/pop_pizza.xml +++ /dev/null @@ -1,45 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M14.645000,14.645000C5.597000,23.693001 0.000000,36.193001 0.000000,50.000000l50.000000,0.000000L14.645000,14.645000z" - android:fillColor="#2979FF"/> - <path - android:pathData="M100.000000,50.000000c0.000000,-13.807000 -5.597000,-26.306999 -14.645000,-35.355000L50.000000,50.000000L100.000000,50.000000z" - android:fillColor="#FF1744"/> - <path - android:pathData="M85.355003,14.645000C76.306999,5.597000 63.806999,0.000000 50.000000,0.000000l0.000000,50.000000L85.355003,14.645000z" - android:fillColor="#0F9D58"/> - <path - android:pathData="M50.000000,0.000000C36.193001,0.000000 23.693001,5.597000 14.645000,14.645000L50.000000,50.000000L50.000000,0.000000z" - android:fillColor="#FFBC00"/> - <path - android:pathData="M50.000000,50.000000l35.355000,35.355000C94.403000,76.307999 100.000000,63.807999 100.000000,50.000000L50.000000,50.000000z" - android:fillColor="#2979FF"/> - <path - android:pathData="M50.000000,100.000000c13.807000,0.000000 26.306999,-5.596000 35.355000,-14.645000L50.000000,50.000000L50.000000,100.000000z" - android:fillColor="#FFBC00"/> - <path - android:pathData="M14.645000,85.355003C23.693001,94.403999 36.193001,100.000000 50.000000,100.000000L50.000000,50.000000L14.645000,85.355003z" - android:fillColor="#0F9D58"/> - <path - android:pathData="M0.000000,50.000000c0.000000,13.808000 5.597000,26.308001 14.645000,35.355000L50.000000,50.000000L0.000000,50.000000z" - android:fillColor="#FF1744"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_stripes.xml b/packages/SystemUI/res/drawable/pop_stripes.xml deleted file mode 100644 index ef6c8e88e2bf..000000000000 --- a/packages/SystemUI/res/drawable/pop_stripes.xml +++ /dev/null @@ -1,36 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#F57C00"/> - <path - android:pathData="M50.000999,100.000000c14.136000,0.000000 26.893000,-5.876000 35.987000,-15.308000L14.013000,84.692001C23.106001,94.124001 35.862999,100.000000 50.000999,100.000000z" - android:fillColor="#E65100"/> - <path - android:pathData="M50.000999,0.000000C35.862999,0.000000 23.106001,5.876000 14.013000,15.308000l71.974998,0.000000C76.893997,5.876000 64.137001,0.000000 50.000999,0.000000z" - android:fillColor="#FFA726"/> - <path - android:pathData="M96.501999,31.631001c-2.423000,-6.127000 -6.020000,-11.660000 -10.514000,-16.323000L14.013000,15.308001C9.517000,19.971001 5.922000,25.503000 3.499000,31.631001L96.501999,31.631001z" - android:fillColor="#FB8C00"/> - <path - android:pathData="M3.499000,68.370003c2.423000,6.128000 6.018000,11.658000 10.514000,16.322001l71.974998,0.000000c4.494000,-4.664000 8.091000,-10.194000 10.514000,-16.322001L3.499000,68.370003z" - android:fillColor="#EF6C00"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_swirl.xml b/packages/SystemUI/res/drawable/pop_swirl.xml deleted file mode 100644 index f87569b4a5f8..000000000000 --- a/packages/SystemUI/res/drawable/pop_swirl.xml +++ /dev/null @@ -1,57 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000C86.898003,27.834999 79.244003,11.688000 76.177002,7.399000c-7.240000,-4.459000 -15.703000,-7.112000 -24.770000,-7.363000C56.247002,2.253000 70.815002,12.456000 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000c20.815001,-37.543999 6.247000,-47.747002 1.407000,-49.964001C50.938000,0.022000 50.472000,0.000000 50.000000,0.000000c-8.627000,0.000000 -16.743999,2.186000 -23.827000,6.032000C31.392000,5.514000 49.251999,6.903000 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000c37.543999,20.816000 47.747002,6.248000 49.965000,1.408000C99.977997,50.938000 100.000000,50.473000 100.000000,50.000000c0.000000,-8.627000 -2.186000,-16.743999 -6.032000,-23.827000C94.486000,31.393000 93.098000,49.251999 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000c43.098000,-0.748000 44.486000,-18.607000 43.967999,-23.827000c-4.186000,-7.708000 -10.344000,-14.188000 -17.791000,-18.773001C79.244003,11.688000 86.898003,27.834999 50.000000,50.000000z" - android:fillColor="#303F9F"/> - <path - android:pathData="M50.000000,50.000000C27.834000,13.103000 11.687000,20.757000 7.398000,23.823999C2.940000,31.063000 0.287000,39.527000 0.035000,48.592999C2.253000,43.752998 12.456000,29.184999 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000C49.251999,6.903000 31.392000,5.514000 26.173000,6.032000c-7.709000,4.187000 -14.188000,10.344000 -18.774000,17.792000C11.687000,20.757000 27.834000,13.103000 50.000000,50.000000z" - android:fillColor="#303F9F"/> - <path - android:pathData="M50.000000,50.000000C12.456000,29.184999 2.253000,43.752998 0.035000,48.592999C0.022000,49.062000 0.000000,49.528000 0.000000,50.000000c0.000000,8.628000 2.186000,16.743999 6.032000,23.827999C5.514000,68.609001 6.902000,50.749001 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000c0.748000,43.098000 18.608000,44.486000 23.827000,43.969002c7.709000,-4.187000 14.188000,-10.344000 18.774000,-17.791000C88.313004,79.244003 72.166000,86.898003 50.000000,50.000000z" - android:fillColor="#303F9F"/> - <path - android:pathData="M50.000000,50.000000c22.166000,36.897999 38.313000,29.243999 42.602001,26.177999c4.458000,-7.240000 7.111000,-15.703000 7.363000,-24.770000C97.747002,56.248001 87.543999,70.816002 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000c-20.815001,37.544998 -6.247000,47.748001 -1.407000,49.965000C49.062000,99.978996 49.528000,100.000000 50.000000,100.000000c8.627000,0.000000 16.743999,-2.185000 23.827000,-6.031000C68.608002,94.486000 50.748001,93.098000 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000C13.103000,72.166000 20.757000,88.313004 23.823000,92.601997c7.240000,4.459000 15.703000,7.112000 24.770000,7.363000C43.752998,97.748001 29.184999,87.544998 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000C6.902000,50.749001 5.514000,68.609001 6.032000,73.828003c4.186000,7.708000 10.344000,14.188000 17.791000,18.773001C20.757000,88.313004 13.103000,72.166000 50.000000,50.000000z" - android:fillColor="#303F9F"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_vortex.xml b/packages/SystemUI/res/drawable/pop_vortex.xml deleted file mode 100644 index 2380e68c4c16..000000000000 --- a/packages/SystemUI/res/drawable/pop_vortex.xml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#F8F8FF"/> - <path - android:pathData="M58.658001,89.648003c-19.330000,0.000000 -35.000000,-15.670000 -35.000000,-35.000000c0.000000,-13.531000 10.969000,-24.500000 24.500000,-24.500000c9.472000,0.000000 17.150000,7.679000 17.150000,17.150000c0.000000,6.631000 -5.375000,12.006000 -12.006000,12.006000c-3.798000,0.000000 -7.004000,-2.522000 -8.045000,-5.982000c1.021000,1.136000 2.497000,1.854000 4.145000,1.854000c2.644000,0.000000 4.853000,-1.841000 5.428000,-4.310000c0.175000,-0.558000 0.271000,-1.150000 0.271000,-1.766000c0.000000,-4.642000 -3.763000,-8.404000 -8.403000,-8.404000c-6.631000,0.000000 -12.006000,5.375000 -12.006000,12.006000c0.000000,9.472000 7.679000,17.149000 17.150000,17.149000c13.531000,0.000000 24.500000,-10.969000 24.500000,-24.500000c0.000000,-19.330000 -15.670000,-35.000000 -35.000000,-35.000000c-12.963000,0.000000 -24.773001,4.935000 -33.657001,13.025000C2.824000,31.087000 0.000000,40.212002 0.000000,50.000000c0.000000,27.615000 22.386000,50.000000 50.000000,50.000000c17.825001,0.000000 33.462002,-9.335000 42.313999,-23.375999C83.431000,84.714996 71.621002,89.648003 58.658001,89.648003z" - android:fillColor="#7BAAF7"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_vortex2.xml b/packages/SystemUI/res/drawable/pop_vortex2.xml deleted file mode 100644 index 0a96b74cf476..000000000000 --- a/packages/SystemUI/res/drawable/pop_vortex2.xml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#D81B60"/> - <path - android:pathData="M21.250000,78.369003c-13.200000,-16.000000 -10.930000,-39.671001 5.070000,-52.870998c12.799000,-10.560000 31.737000,-8.743000 42.294998,4.057000c8.448000,10.239000 6.996000,25.389000 -3.244000,33.837002c-8.191000,6.759000 -20.311001,5.596000 -27.068001,-2.596000c-5.408000,-6.554000 -4.478000,-16.249001 2.076000,-21.656000c5.242000,-4.325000 12.998000,-3.581000 17.323999,1.661000c3.460000,4.194000 2.865000,10.399000 -1.330000,13.859000c-3.354000,2.769000 -8.318000,2.293000 -11.087000,-1.062000c-2.214000,-2.685000 -1.833000,-6.655000 0.851000,-8.870000c2.147000,-1.771000 5.324000,-1.468000 7.096000,0.681000c1.393000,1.688000 1.174000,4.165000 -0.464000,5.596000c0.409000,-0.564000 0.657000,-1.253000 0.657000,-2.004000c0.000000,-1.021000 -0.455000,-1.928000 -1.165000,-2.556000c-0.067000,-0.112000 -0.134000,-0.226000 -0.220000,-0.329000c-1.135000,-1.373000 -3.168000,-1.568000 -4.542000,-0.435000c-1.719000,1.417000 -1.962000,3.958000 -0.544000,5.677000c1.771000,2.146000 4.949000,2.451000 7.096000,0.680000c2.684000,-2.215000 3.064000,-6.186000 0.851000,-8.870000c-2.769000,-3.356000 -7.732000,-3.831000 -11.087000,-1.063000c-4.195000,3.460000 -4.790000,9.665000 -1.330000,13.859000c4.326000,5.244000 12.082000,5.987000 17.323999,1.662000c6.554000,-5.407000 7.484000,-15.102000 2.076000,-21.656000c-6.758000,-8.191000 -18.875999,-9.354000 -27.069000,-2.596000c-10.239000,8.448000 -11.691000,23.598000 -3.244000,33.837002c10.560000,12.800000 29.497000,14.616000 42.296001,4.056000c16.000000,-13.199000 18.270000,-36.869999 5.070000,-52.868999C68.397003,5.620000 52.516998,-0.139000 37.205002,1.659000c-8.665000,2.287000 -16.410999,6.836000 -22.561001,12.985000C5.597000,23.693001 0.000000,36.193001 0.000000,50.000000c0.000000,13.808000 5.597000,26.308001 14.645000,35.355000C23.693001,94.403999 36.193001,100.000000 50.000000,100.000000c11.935000,0.000000 22.886999,-4.187000 31.482000,-11.164000C61.909000,100.523003 36.202999,96.495003 21.250000,78.369003z" - android:fillColor="#F06292"/> -</vector> diff --git a/packages/SystemUI/res/drawable/qs_subhead_caret.xml b/packages/SystemUI/res/drawable/qs_subhead_caret.xml deleted file mode 100644 index 13a168d758aa..000000000000 --- a/packages/SystemUI/res/drawable/qs_subhead_caret.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - - <path - android:fillColor="@color/qs_subhead" - android:pathData="M14.0,20.0l10.0,10.0 10.0,-10.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/qs_tile_background.xml b/packages/SystemUI/res/drawable/qs_tile_background.xml deleted file mode 100644 index 96891c14bd33..000000000000 --- a/packages/SystemUI/res/drawable/qs_tile_background.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2012, 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"> - <item android:state_pressed="true"> - <color android:color="#212121" /> - </item> - <item> - <color android:color="#161616" /> - </item> -</selector> diff --git a/packages/SystemUI/res/drawable/quick_header_bg.xml b/packages/SystemUI/res/drawable/quick_header_bg.xml deleted file mode 100644 index 920e6f5ef086..000000000000 --- a/packages/SystemUI/res/drawable/quick_header_bg.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2015 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 - --> - -<ripple xmlns:android="http://schemas.android.com/apk/res/android" - android:color="?android:attr/colorControlHighlight" > - <item android:drawable="?android:attr/colorPrimary"/> -</ripple> diff --git a/packages/SystemUI/res/drawable/scorecard_gameover.xml b/packages/SystemUI/res/drawable/scorecard_gameover.xml deleted file mode 100644 index f663a661f3f1..000000000000 --- a/packages/SystemUI/res/drawable/scorecard_gameover.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" - > - <corners - android:radius="8dp" /> - <solid - android:color="#ffff0000" /> -</shape> diff --git a/packages/SystemUI/res/drawable/stat_notify_more.xml b/packages/SystemUI/res/drawable/stat_notify_more.xml deleted file mode 100644 index 50f12861afe8..000000000000 --- a/packages/SystemUI/res/drawable/stat_notify_more.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - ~ Copyright (C) 2014 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:width="16dp" - android:height="16dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M22.000000,3.000000L7.000000,3.000000C6.300000,3.000000 5.800000,3.400000 5.400000,3.900000L0.000000,12.000000l5.400000,8.100000c0.400000,0.500000 1.000000,0.900000 1.700000,0.900000L22.000000,21.000000c1.100000,0.000000 2.000000,-0.900000 2.000000,-2.000000L24.000000,5.000000C24.000000,3.900000 23.100000,3.000000 22.000000,3.000000zM9.000000,13.500000c-0.800000,0.000000 -1.500000,-0.700000 -1.500000,-1.500000s0.700000,-1.500000 1.500000,-1.500000c0.800000,0.000000 1.500000,0.700000 1.500000,1.500000S9.800000,13.500000 9.000000,13.500000zM14.000000,13.500000c-0.800000,0.000000 -1.500000,-0.700000 -1.500000,-1.500000s0.700000,-1.500000 1.500000,-1.500000c0.800000,0.000000 1.500000,0.700000 1.500000,1.500000S14.800000,13.500000 14.000000,13.500000zM19.000000,13.500000c-0.800000,0.000000 -1.500000,-0.700000 -1.500000,-1.500000s0.700000,-1.500000 1.500000,-1.500000c0.800000,0.000000 1.500000,0.700000 1.500000,1.500000S19.799999,13.500000 19.000000,13.500000z" - android:fillColor="#FFFFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml deleted file mode 100644 index ba0709e9aa0e..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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. ---> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:height="17dp" - android:width="17dp" - android:viewportHeight="48" - android:viewportWidth="48" > - <group - android:name="ic_screen_rotation_48px_outlines" - android:translateX="24" - android:translateY="24" > - <group - android:name="ic_screen_rotation_48px_outlines_pivot" - android:translateX="-24.15" - android:translateY="-24.25" > - <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - <group - android:name="device" - android:translateX="24.14999" - android:translateY="24.25" > - <path - android:name="body" - android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - </group> - </vector> -</inset> diff --git a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml deleted file mode 100644 index 46a1f3575f86..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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. ---> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:height="17dp" - android:width="17dp" - android:viewportHeight="48" - android:viewportWidth="48" > - <group - android:name="icon" - android:translateX="24" - android:translateY="24" > - <group - android:name="icon_pivot" - android:translateX="-24.15" - android:translateY="-24.25" > - <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - <group - android:name="device" - android:translateX="24.14999" - android:translateY="24.25" > - <path - android:name="device_1" - android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - </group> - </vector> -</inset> diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml deleted file mode 100644 index 1dedd5d4daef..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="23dp" - android:height="18dp" - android:viewportWidth="23.0" - android:viewportHeight="18.0"> - <path - android:fillColor="@android:color/white" - android:pathData="M19.4,16.6l-1.1,-1.1L8,5L5.1,2.2L4.2,3.1l2,2H5.7c-0.8,0 -1.4,0.6 -1.4,1.4v8c0,0.8 0.6,1.4 1.4,1.4h11.4l1.5,1.5L19.4,16.6zM18.7,6.5c0,-0.8 -0.6,-1.4 -1.4,-1.4h-2.9V3.6c0,-0.8 -0.6,-1.4 -1.4,-1.4h-3C9.2,2.1 8.6,2.8 8.6,3.6v0.2L18.7,14C18.7,14 18.7,6.5 18.7,6.5zM12.9,5.1H10V3.6h2.9V5.1z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml deleted file mode 100644 index 5c9be5c50a13..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2017, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h6v-3h2V9H12.09zM20,13h-2v3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H20V13z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_in.xml b/packages/SystemUI/res/drawable/stat_sys_signal_in.xml deleted file mode 100644 index 7e6e09b9c846..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_signal_in.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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:autoMirrored="true" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,12.2l-2.0,3.5l-2.0,-3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_inout.xml b/packages/SystemUI/res/drawable/stat_sys_signal_inout.xml deleted file mode 100644 index b7b6f0f56749..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_signal_inout.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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:autoMirrored="true" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,12.2l-2.0,3.5l-2.0,-3.5z" /> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,15.7l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_out.xml b/packages/SystemUI/res/drawable/stat_sys_signal_out.xml deleted file mode 100644 index 910c0355f5a9..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_signal_out.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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:autoMirrored="true" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,15.7l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_in.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_in.xml deleted file mode 100644 index ba3d4e60c6e7..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_in.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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:autoMirrored="true" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,18.3l-2.0,3.5l-2.0,-3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_inout.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_inout.xml deleted file mode 100644 index 1f3b68fd5d72..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_inout.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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:autoMirrored="true" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,18.3l-2.0,3.5l-2.0,-3.5z" /> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,21.8l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_out.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_out.xml deleted file mode 100644 index 24c6b1e871fa..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_out.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 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:autoMirrored="true" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,21.8l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/sun2.xml b/packages/SystemUI/res/drawable/sun2.xml deleted file mode 100644 index 6d2d5041f5ab..000000000000 --- a/packages/SystemUI/res/drawable/sun2.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 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:width="48.0dp" - android:height="48.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - <path - android:pathData="M40.000000,17.400000L40.000000,8.000000l-9.400000,0.000000L24.000000,1.400000L17.400000,8.000000L8.000000,8.000000l0.000000,9.400000L1.400000,24.000000L8.000000,30.600000L8.000000,40.000000l9.400000,0.000000l6.600000,6.600000l6.600000,-6.600000L40.000000,40.000000l0.000000,-9.400000l6.600000,-6.600000L40.000000,17.400000zM24.000000,36.000000c-6.600000,0.000000 -12.000000,-5.400000 -12.000000,-12.000000s5.400000,-12.000000 12.000000,-12.000000c6.600000,0.000000 12.000000,5.400000 12.000000,12.000000S30.600000,36.000000 24.000000,36.000000zM24.000000,16.000000c-4.400000,0.000000 -8.000000,3.600000 -8.000000,8.000000c0.000000,4.400000 3.600000,8.000000 8.000000,8.000000s8.000000,-3.600000 8.000000,-8.000000C32.000000,19.600000 28.400000,16.000000 24.000000,16.000000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/tv_pip_outline.xml b/packages/SystemUI/res/drawable/tv_pip_outline.xml deleted file mode 100644 index c84438c2e55e..000000000000 --- a/packages/SystemUI/res/drawable/tv_pip_outline.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2016 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. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <stroke android:width="2dp" android:color="#EEEEEE" /> -</shape> diff --git a/packages/SystemUI/res/drawable/volume_dialog_background.xml b/packages/SystemUI/res/drawable/volume_dialog_background.xml deleted file mode 100644 index 996ac5e030da..000000000000 --- a/packages/SystemUI/res/drawable/volume_dialog_background.xml +++ /dev/null @@ -1,18 +0,0 @@ -<!-- - Copyright (C) 2015 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. ---> -<shape xmlns:android="http://schemas.android.com/apk/res/android" > - <solid android:color="?android:attr/colorBackgroundFloating" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 6b2538770360..eed44dd0d8a4 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Swerwing"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Werkmodus is aangeskakel."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Databespaarder is afgeskakel."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Databespaarder is aangeskakel."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensorprivaatheid is afgeskakel."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensorprivaatheid is aangeskakel."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Skermhelderheid"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Laai tans"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G-data is laat wag"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> ander programme</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> ander program</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors is af"</string> + <string name="device_services" msgid="1191212554435440592">"Toesteldienste"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index db97510ef57b..7c09112b3fb2 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5ጂ"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5ጂ+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"በማዛወር ላይ"</string> <string name="data_connection_edge" msgid="871835227939216682">"ኤጅ"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"የሥራ ሁነታ በርቷል።"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ውሂብ ቆጣቢ ጠፍቷል።"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ውሂብ ቆጣቢ በርቷል።"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"የዳሳሽ ግላዊነት ጠፍቷል።"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"የዳሳሽ ግላዊነት በርቷል።"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ብሩህነት ያሳዩ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ኃይል በመሙላት ላይ"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2ጂ-3ጂ ውሂብ ላፍታ ቆሟል"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index ff98366e8f00..16abb680d45e 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"شبكة الجيل الرابع أو أحدث"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"شبكة 5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"شبكة 5G والأحدث"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"التجوال"</string> <string name="data_connection_edge" msgid="871835227939216682">"شبكة EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"تم تشغيل وضع العمل."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"تم إيقاف توفير البيانات."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"تم تشغيل توفير البيانات."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"تم إيقاف \"خصوصية أجهزة الاستشعار\"."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"تم تفعيل \"خصوصية أجهزة الاستشعار\"."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"سطوع الشاشة"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"جارٍ الشحن"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"بيانات شبكات الجيل الثاني والثالث متوقفة مؤقتًا"</string> @@ -908,4 +912,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index d7b218d1c7c7..25f7b5b02370 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -42,7 +42,7 @@ <string name="status_bar_settings_mute_label" msgid="554682549917429396">"মিউট"</string> <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"স্বয়ং"</string> <string name="status_bar_settings_notifications" msgid="397146176280905137">"জাননীসমূহ"</string> - <string name="bluetooth_tethered" msgid="7094101612161133267">"ব্লুটুথ টেডাৰিং কৰা হ\'ল"</string> + <string name="bluetooth_tethered" msgid="7094101612161133267">"ব্লুটুথ টেডাৰিং কৰা হ’ল"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ইনপুট পদ্ধতি ছেট আপ কৰক"</string> <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"বাস্তৱিক কীব\'ৰ্ড"</string> <string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ত প্ৰৱেশ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক অনুমতি দিবনে?"</string> @@ -64,7 +64,7 @@ <string name="global_action_screenshot" msgid="8329831278085426283">"স্ক্ৰীণশ্বট"</string> <string name="screenshot_saving_ticker" msgid="7403652894056693515">"স্ক্ৰীণশ্বট ছেভ কৰি থকা হৈছে…"</string> <string name="screenshot_saving_title" msgid="8242282144535555697">"স্ক্ৰীণশ্বট ছেভ কৰি থকা হৈছে…"</string> - <string name="screenshot_saved_title" msgid="5637073968117370753">"স্ক্ৰীণশ্বট ছেভ কৰা হ\'ল"</string> + <string name="screenshot_saved_title" msgid="5637073968117370753">"স্ক্ৰীণশ্বট ছেভ কৰা হ’ল"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"আপোনাৰ স্ক্ৰীণশ্বট চাবলৈ টিপক"</string> <string name="screenshot_failed_title" msgid="7612509838919089748">"স্ক্ৰীণশ্বট ছেভ কৰিব পৰা নগ\'ল"</string> <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"স্ক্ৰীণশ্বট আকৌ ল\'বলৈ চেষ্টা কৰক"</string> @@ -81,10 +81,10 @@ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"বাতিল কৰক"</string> <string name="screenrecord_share_label" msgid="4197867360204019389">"শ্বেয়াৰ কৰক"</string> <string name="screenrecord_delete_label" msgid="7893716870917824013">"মচক"</string> - <string name="screenrecord_cancel_success" msgid="7768976011702614782">"স্ক্রীণ ৰেকৰ্ড কৰাটো বাতিল কৰা হ\'ল"</string> - <string name="screenrecord_save_message" msgid="4733982661301846778">"স্ক্রীণ ৰেকৰ্ডিং ছেভ কৰা হ\'ল, চাবলৈ টিপক"</string> - <string name="screenrecord_delete_description" msgid="5743190456090354585">"স্ক্রীণ ৰেকৰ্ডিং মচা হ\'ল"</string> - <string name="screenrecord_delete_error" msgid="8154904464563560282">"স্ক্রীণ ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ\'ল"</string> + <string name="screenrecord_cancel_success" msgid="7768976011702614782">"স্ক্রীণ ৰেকৰ্ড কৰাটো বাতিল কৰা হ’ল"</string> + <string name="screenrecord_save_message" msgid="4733982661301846778">"স্ক্রীণ ৰেকৰ্ডিং ছেভ কৰা হ’ল, চাবলৈ টিপক"</string> + <string name="screenrecord_delete_description" msgid="5743190456090354585">"স্ক্রীণ ৰেকৰ্ডিং মচা হ’ল"</string> + <string name="screenrecord_delete_error" msgid="8154904464563560282">"স্ক্রীণ ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ’ল"</string> <string name="screenrecord_permission_error" msgid="1526755299469001000">"অনুমতি পাব পৰা নগ\'ল"</string> <string name="usb_preference_title" msgid="6551050377388882787">"ইউএছবিৰে ফাইল স্থানান্তৰণৰ বিকল্পসমূহ"</string> <string name="use_mtp_button_title" msgid="4333504413563023626">"মিডিয়া প্লেয়াৰ (এমটিপি) হিচাপে সংলগ্ন কৰক"</string> @@ -120,8 +120,8 @@ <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"মুখমণ্ডলৰ আইকন"</string> <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"উপযোগিতা অনুসৰি জুম কৰা বুটাম।"</string> <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"স্ক্ৰীণৰ আকাৰ ডাঙৰ কৰিবলৈ জুম কৰক।"</string> - <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ব্লুটুথ সংযোগ হ\'ল।"</string> - <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"ব্লুটুথ সংযোগ বিচ্ছিন্ন কৰা হ\'ল।"</string> + <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ব্লুটুথ সংযোগ হ’ল।"</string> + <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"ব্লুটুথ সংযোগ বিচ্ছিন্ন কৰা হ’ল।"</string> <string name="accessibility_no_battery" msgid="358343022352820946">"বেটাৰি শেষ"</string> <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"বেটাৰিৰ এডাল দণ্ড।"</string> <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"বেটাৰিৰ দুডাল দণ্ড।"</string> @@ -137,9 +137,9 @@ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"ডেটা ছংনেলৰ তিনিডাল দণ্ড।"</string> <string name="accessibility_data_three_bars" msgid="9167670452395038520">"ডেটা ছিংগনেলত তিনিডাল দণ্ড আছে।"</string> <string name="accessibility_data_signal_full" msgid="2708384608124519369">"ডেটা ছিগনেল পূৰা আছে।"</string> - <string name="accessibility_wifi_name" msgid="7202151365171148501">"<xliff:g id="WIFI">%s</xliff:g>ৰ লগত সংযোগ কৰা হ\'ল।"</string> - <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"<xliff:g id="BLUETOOTH">%s</xliff:g>ৰ লগত সংযোগ কৰা হ\'ল।"</string> - <string name="accessibility_cast_name" msgid="4026393061247081201">"<xliff:g id="CAST">%s</xliff:g>ত সংযোগ হ\'ল।"</string> + <string name="accessibility_wifi_name" msgid="7202151365171148501">"<xliff:g id="WIFI">%s</xliff:g>ৰ লগত সংযোগ কৰা হ’ল।"</string> + <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"<xliff:g id="BLUETOOTH">%s</xliff:g>ৰ লগত সংযোগ কৰা হ’ল।"</string> + <string name="accessibility_cast_name" msgid="4026393061247081201">"<xliff:g id="CAST">%s</xliff:g>ত সংযোগ হ’ল।"</string> <string name="accessibility_no_wimax" msgid="4329180129727630368">"কোনো WiMAX নাই।"</string> <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAXৰ এডাল দণ্ড৷"</string> <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAXৰ দুডাল দণ্ড আছে।"</string> @@ -167,14 +167,16 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"এলটিই"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"এলটিই+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ৰ\'মিং"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"ৱাই-ফাই"</string> <string name="accessibility_no_sim" msgid="8274017118472455155">"ছিম নাই।"</string> - <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> + <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> <string name="cell_data_off" msgid="1051264981229902873">"অফ অৱস্থাত আছে"</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ব্লুটুথ টেডাৰিং।"</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"এয়াৰপ্লেইন ম\'ড।"</string> @@ -206,30 +208,30 @@ <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"কৰ্মস্থানৰ প্ৰ\'ফাইলৰ লক স্ক্ৰীণ"</string> <string name="accessibility_desc_close" msgid="7479755364962766729">"বন্ধ কৰক"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> - <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"ৱাই-ফাই অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"ৱাই-ফাই অন কৰা হ\'ল।"</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_wifi_changed_off" msgid="8716484460897819400">"ৱাই-ফাই অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"ৱাই-ফাই অন কৰা হ’ল।"</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_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_off" msgid="898107593453022935">"অসুবিধা নিদিব বন্ধ কৰা হ’ল।"</string> <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"অসুবিধা নিদিব অন কৰা হৈছে।"</string> <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> <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"ব্লুটুথ সংযোগ কৰি থকা হৈছে।"</string> - <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ব্লুটুথ সংযোগ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ব্লুটুথ অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ব্লুটুথ অন কৰা হ\'ল।"</string> + <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ব্লুটুথ সংযোগ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ব্লুটুথ অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ব্লুটুথ অন কৰা হ’ল।"</string> <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"অৱস্থান সবিশেষ অফ হৈ আছে।"</string> <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"অৱস্থান সবিশেষ অন হৈ আছে।"</string> - <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"অৱস্থান সবিশেষ অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"অৱস্থান সবিশেষ অন কৰা হ\'ল।"</string> + <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"অৱস্থান সবিশেষ অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"অৱস্থান সবিশেষ অন কৰা হ’ল।"</string> <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g>ৰ বাবে এলাৰ্ম ছেট কৰা হৈছে।"</string> <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"পেনেল বন্ধ কৰক।"</string> <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"অধিক সময়।"</string> @@ -237,26 +239,28 @@ <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"ফ্লাশ্বলাইট অফ হৈ আছে।"</string> <string name="accessibility_quick_settings_flashlight_unavailable" msgid="8012811023312280810">"ফ্লাশ্বলাইট উপলব্ধ নহয়।"</string> <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"ফ্লাশ্বলাইট অন হৈ আছে৷"</string> - <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"ফ্লাশ্বলাইট অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ফ্লাশ্বলাইট অন কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"ৰং বিপৰীতকৰণ অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"ৰং বিপৰীতকৰণ অন কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ম\'বাইল হ\'টস্প\'ট অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ম\'বাইল হ\'টস্প\'ট অন কৰা হ\'ল।"</string> - <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"স্ক্ৰীণ কাষ্টিং বন্ধ কৰা হ\'ল।"</string> + <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"ফ্লাশ্বলাইট অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ফ্লাশ্বলাইট অন কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"ৰং বিপৰীতকৰণ অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"ৰং বিপৰীতকৰণ অন কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ম’বাইল হ\'টস্প\'ট অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ম’বাইল হ\'টস্প\'ট অন কৰা হ’ল।"</string> + <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"স্ক্ৰীণ কাষ্টিং বন্ধ কৰা হ’ল।"</string> <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"কৰ্মস্থান ম\'ড অফ হৈ আছে।"</string> <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"কৰ্মস্থান ম\'ড অন হৈ আছে।"</string> - <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"কৰ্মস্থান ম\'ড অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"কৰ্মস্থান ম\'ড অন কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ডেটা সঞ্চয়কাৰী সুবিধা অফ কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ডেটা সঞ্চয়কাৰী সুবিধা অন কৰা হ\'ল।"</string> + <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"কৰ্মস্থান ম\'ড অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"কৰ্মস্থান ম\'ড অন কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ডেটা সঞ্চয়কাৰী সুবিধা অফ কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ডেটা সঞ্চয়কাৰী সুবিধা অন কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"ছেন্সৰৰ গোপনীয়তা অফ কৰা হৈছে।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"ছেন্সৰৰ গোপনীয়তা অন কৰা হৈছে।"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ডিছপ্লেৰ উজ্জ্বলতা"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"চ্চার্জ কৰি থকা হৈছে"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ডেটা পজ কৰা হৈছে"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ডেটা পজ কৰা হৈছে"</string> - <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"ম\'বাইল ডেটা পজ কৰা হৈছে"</string> + <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"ম’বাইল ডেটা পজ কৰা হৈছে"</string> <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"ডেটা পজ কৰা হৈছে"</string> - <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"আপুনি নির্ধাৰণ কৰা ডেটাৰ সীমা শেষ হৈছে। আপুনি এতিয়া ম\'বাইল ডেটা ব্যৱহাৰ কৰিব নোৱাৰে। \n\nযদিহে আপুনি আকৌ ম\'বাইল ডেটা ব্যৱহাৰ কৰে তেন্তে ডেটাৰ ব্যৱহাৰৰ বাবে মাচুল ভৰিবলগীয়া হ\'ব পাৰে।"</string> + <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"আপুনি নির্ধাৰণ কৰা ডেটাৰ সীমা শেষ হৈছে। আপুনি এতিয়া ম’বাইল ডেটা ব্যৱহাৰ কৰিব নোৱাৰে। \n\nযদিহে আপুনি আকৌ ম’বাইল ডেটা ব্যৱহাৰ কৰে তেন্তে ডেটাৰ ব্যৱহাৰৰ বাবে মাচুল ভৰিবলগীয়া হ’ব পাৰে।"</string> <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"পুনৰ আৰম্ভ কৰক"</string> <string name="gps_notification_searching_text" msgid="8574247005642736060">"জিপিএছ সন্ধান কৰি থকা হৈছে"</string> <string name="gps_notification_found_text" msgid="4619274244146446464">"জিপিএছএ অৱস্থান ছেট কৰিছে"</string> @@ -271,8 +275,8 @@ <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"জাননীৰ ছেটিংসমূহ"</string> <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ছেটিংসমূহ"</string> <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"আপোনাৰ ফ\'নৰ স্ক্ৰীণ স্বয়ংক্ৰিয়ভাৱে ঘূৰিব৷"</string> - <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"স্ক্ৰীণ লেণ্ডস্কেপ দিশত লক কৰা হ\'ল।"</string> - <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"স্ক্ৰীণ প\'ৰ্ট্ৰেইট দিশত লক কৰা হ\'ল।"</string> + <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"স্ক্ৰীণ লেণ্ডস্কেপ দিশত লক কৰা হ’ল।"</string> + <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"স্ক্ৰীণ প\'ৰ্ট্ৰেইট দিশত লক কৰা হ’ল।"</string> <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"আপোনাৰ ফ\'নৰ স্ক্ৰীণ এতিয়া স্বয়ংক্ৰিয়ভাৱে ঘূৰিব৷"</string> <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"স্ক্ৰীণখন এতিয়া লেণ্ডস্কেইপ দিশত লক কৰা অৱস্থাত আছে।"</string> <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"স্ক্ৰীণখন এতিয়া প\'ৰ্ট্ৰেইট দিশত লক কৰা অৱস্থাত আছে।"</string> @@ -299,7 +303,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"স্বয়ং-ঘূৰ্ণন"</string> <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীণ"</string> <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> ম\'ড"</string> - <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ঘূৰ্ণন লক কৰা হ\'ল"</string> + <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ঘূৰ্ণন লক কৰা হ’ল"</string> <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"প\'ৰ্ট্ৰেইট"</string> <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"লেণ্ডস্কেইপ"</string> <string name="quick_settings_ime_label" msgid="7073463064369468429">"ইনপুট পদ্ধতি"</string> @@ -331,7 +335,7 @@ <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ৰং ওলোটা কৰক"</string> <string name="quick_settings_color_space_label" msgid="853443689745584770">"ৰং শুধৰণী কৰা ম\'ড"</string> <string name="quick_settings_more_settings" msgid="326112621462813682">"অধিক ছেটিং"</string> - <string name="quick_settings_done" msgid="3402999958839153376">"সম্পন্ন কৰা হ\'ল"</string> + <string name="quick_settings_done" msgid="3402999958839153376">"সম্পন্ন কৰা হ’ল"</string> <string name="quick_settings_connected" msgid="1722253542984847487">"সংযোগ কৰা হ’ল"</string> <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"সংযুক্ত, বেটাৰি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="quick_settings_connecting" msgid="47623027419264404">"সংযোগ কৰি থকা হৈছে..."</string> @@ -345,7 +349,7 @@ </plurals> <string name="quick_settings_notifications_label" msgid="4818156442169154523">"জাননীসমূহ"</string> <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ফ্লাশ্বলাইট"</string> - <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ম\'বাইল ডেটা"</string> + <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ম’বাইল ডেটা"</string> <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ডেটা ব্যৱহাৰ"</string> <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"বাকী থকা ডেটা"</string> <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"সর্ব্বোচ সীমা"</string> @@ -364,7 +368,7 @@ <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"আনটো এপ্ ব্য়ৱহাৰ কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string> <string name="recents_quick_scrub_onboarding" msgid="2778062804333285789">"খৰতকীয়াকৈ আনটো এপ্ ব্য়ৱহাৰ কৰিবলৈ সোঁফালে টানক"</string> <string name="quick_step_accessibility_toggle_overview" msgid="7171470775439860480">"অৱলোকন ট’গল কৰক"</string> - <string name="expanded_header_battery_charged" msgid="5945855970267657951">"চ্চার্জ হ\'ল"</string> + <string name="expanded_header_battery_charged" msgid="5945855970267657951">"চ্চার্জ হ’ল"</string> <string name="expanded_header_battery_charging" msgid="205623198487189724">"চ্চার্জ হৈ আছে"</string> <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"বেটাৰিৰ চ্চাৰ্জ সম্পূর্ণ হ\'বলৈ <xliff:g id="CHARGING_TIME">%s</xliff:g> বাকী"</string> <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"চ্চার্জ কৰি থকা নাই"</string> @@ -419,7 +423,7 @@ <string name="user_logout_notification_text" msgid="3350262809611876284">"বর্তমানৰ ব্যৱহাৰকাৰীক লগ আউট কৰক"</string> <string name="user_logout_notification_action" msgid="1195428991423425062">"ব্যৱহাৰকাৰীক লগ আউট কৰক"</string> <string name="user_add_user_title" msgid="4553596395824132638">"নতুন ব্যৱহাৰকাৰী যোগ কৰিবনে?"</string> - <string name="user_add_user_message_short" msgid="2161624834066214559">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ স্থান ছেট আপ কৰা প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে নিজৰ লগতে আন ব্যৱহাৰকাৰীৰো এপ্ আপডেট কৰিব পাৰে।"</string> + <string name="user_add_user_message_short" msgid="2161624834066214559">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ স্থান ছেট আপ কৰা প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে নিজৰ লগতে আন ব্যৱহাৰকাৰীৰো এপ্ আপডে’ট কৰিব পাৰে।"</string> <string name="user_limit_reached_title" msgid="7374910700117359177">"অধিকতম ব্যৱহাৰকাৰী সৃষ্টি কৰা হ’ল"</string> <plurals name="user_limit_reached_message" formatted="false" msgid="1855040563671964242"> <item quantity="one">আপুনি <xliff:g id="COUNT">%d</xliff:g> জনলৈকে ব্যৱহাৰকাৰী যোগ কৰিব পাৰে।</item> @@ -507,7 +511,7 @@ <string name="accessibility_volume_expand" msgid="5946812790999244205">"সম্প্ৰসাৰণ কৰক"</string> <string name="accessibility_volume_collapse" msgid="3609549593031810875">"সংকুচিত কৰক"</string> <string name="accessibility_output_chooser" msgid="8185317493017988680">"আউটপুট ডিভাইচ সলনি কৰক"</string> - <string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্ৰীণ পিন কৰা হ\'ল"</string> + <string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্ৰীণ পিন কৰা হ’ল"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ \'পিছলৈ যাওক\' আৰু \'অৱলোকন\'-ত স্পৰ্শ কৰি থাকক।"</string> <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ পিছলৈ যাওক আৰু হ\'মত স্পৰ্শ কৰি সেঁচি ধৰক।"</string> <string name="screen_pinning_description_accessible" msgid="426190689254018656">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ \'অৱলোকন\'-ত স্পৰ্শ কৰি থাকক।"</string> @@ -516,8 +520,8 @@ <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"এই স্ক্ৰীণখন আনপিন কৰিবলৈ পিছলৈ যাওক আৰু হ\'ম বুটামত স্পৰ্শ কৰি হেঁচি ধৰক।"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"বুজি পালোঁ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"নালাগে, ধন্যবাদ"</string> - <string name="screen_pinning_start" msgid="1022122128489278317">"স্ক্ৰীণ পিন কৰা হ\'ল"</string> - <string name="screen_pinning_exit" msgid="5187339744262325372">"স্ক্ৰীণ আনপিন কৰা হ\'ল"</string> + <string name="screen_pinning_start" msgid="1022122128489278317">"স্ক্ৰীণ পিন কৰা হ’ল"</string> + <string name="screen_pinning_exit" msgid="5187339744262325372">"স্ক্ৰীণ আনপিন কৰা হ’ল"</string> <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> লুকুৱাবনে?"</string> <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"আপুনি ইয়াক পৰৱৰ্তী সময়ত ছেটিংসমূহত অন কৰিলে ই পুনৰ প্ৰকট হ\'ব।"</string> <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"লুকুৱাওক"</string> @@ -576,8 +580,8 @@ <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"হ\'টস্প\'ট"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string> <string name="tuner_warning_title" msgid="7094689930793031682">"কিছুমানৰ বাবে আমোদজনক হয় কিন্তু সকলোৰে বাবে নহয়"</string> - <string name="tuner_warning" msgid="8730648121973575701">"System UI Tunerএ আপোনাক Android ব্যৱহাৰকাৰী ইণ্টাৰফেইচ সলনি কৰিবলৈ আৰু নিজৰ উপযোগিতা অনুসৰি ব্যৱহাৰ কৰিবলৈ অতিৰিক্ত সুবিধা প্ৰদান কৰে। এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ\'ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string> - <string name="tuner_persistent_warning" msgid="8597333795565621795">"এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ\'ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tunerএ আপোনাক Android ব্যৱহাৰকাৰী ইণ্টাৰফেইচ সলনি কৰিবলৈ আৰু নিজৰ উপযোগিতা অনুসৰি ব্যৱহাৰ কৰিবলৈ অতিৰিক্ত সুবিধা প্ৰদান কৰে। এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ’ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ’ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string> <string name="got_it" msgid="2239653834387972602">"বুজি পালোঁ"</string> <string name="tuner_toast" msgid="603429811084428439">"অভিনন্দন! ছেটিংসমূহত System UI Tuner যোগ কৰা হৈছে"</string> <string name="remove_from_settings" msgid="8389591916603406378">"ছেটিংসমূহৰ পৰা আঁতৰাওক"</string> @@ -600,7 +604,7 @@ <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"অফ"</string> <string name="power_notification_controls_description" msgid="4372459941671353358">"জাননী নিয়ন্ত্ৰণৰ অধিক কৰ্তৃত্বৰ সৈতে আপুনি এটা এপৰ জাননীৰ গুৰুত্বৰ স্তৰ ০ৰ পৰা ৫লৈ ছেট কৰিব পাৰে।\n\n"<b>"স্তৰ ৫"</b>" \n- জাননী তালিকাৰ একেবাৰে ওপৰত দেখুৱাওক \n- সম্পূৰ্ণ স্ক্ৰীণত থাকোঁতে ব্যাঘাত জন্মাবলৈ অনুমতি দিয়ক\n- সদায় ভুমুকি মাৰিবলৈ দিয়ক\n\n"<b>"স্তৰ ৪"</b>" \n- সম্পূৰ্ণ স্ক্ৰীণত থাকোঁতে ব্যাঘাত জন্মাবলৈ নিদিব\n- সদায় ভুমুকি মাৰিবলৈ দিয়ক\n\n"<b>"স্তৰ ৩"</b>" \n- সম্পূৰ্ণ স্ক্ৰীণত থাকোঁতে ব্যাঘাত জন্মাবলৈ নিদিব\n- কেতিয়াও ভুমুকি মাৰিবলৈ নিদিব\n\n"<b>"স্তৰ ২"</b>" \n- সম্পূর্ণ স্ক্ৰীণত থাকোঁতে ব্যাঘাত জন্মাবলৈ নিদিব \n- কেতিয়াও ভুমুকি মাৰিবলৈ নিদিব\n- কেতিয়াও শব্দ আৰু কম্পন কৰিবলৈ নিদিব\n\n"<b>" স্তৰ ১"</b>" \n- সম্পূৰ্ণ স্ক্ৰীণত থাকোঁতে ব্যাঘাত জন্মাবলৈ নিদিব\n- কেতিয়াও ভুমুকি মাৰিবলৈ নিদিব\n-কেতিয়াও শব্দ আৰু কম্পন কৰিবলৈ নিদিব \n- লক স্ক্ৰীণ আৰু স্থিতি দণ্ডৰ পৰা লুকুৱাই ৰাখক \n- জাননী তালিকাৰ একেবাৰে তলত দেখুৱাওক\n\n"<b>"স্তৰ ০"</b>" \n- এই এপৰ সকলো জাননী অৱৰোধ কৰক"</string> <string name="notification_header_default_channel" msgid="7506845022070889909">"জাননীসমূহ"</string> - <string name="notification_channel_disabled" msgid="344536703863700565">"আপোনাক এই জাননীসমূহ আৰু দেখুওৱা নহ\'ব"</string> + <string name="notification_channel_disabled" msgid="344536703863700565">"আপোনাক এই জাননীসমূহ আৰু দেখুওৱা নহ’ব"</string> <string name="notification_channel_minimized" msgid="1664411570378910931">"এই জাননীসমূহ মিনিমাইজ কৰি থোৱা হ\'ব"</string> <string name="notification_channel_silenced" msgid="2877199534497961942">"এই জাননী নিৰৱে দেখুওৱা হ’ব"</string> <string name="notification_channel_unsilenced" msgid="4790904571552394137">"এই জাননীবোৰে আপোনাক সতৰ্ক কৰিব"</string> @@ -635,7 +639,7 @@ <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"এই চ্চেনেলৰ পৰা জাননী দিবলৈ অনুমতি দিয়ক"</string> <string name="notification_more_settings" msgid="816306283396553571">"অধিক ছেটিং"</string> <string name="notification_app_settings" msgid="420348114670768449">"নিজৰ উপযোগিতা অনুসৰি"</string> - <string name="notification_done" msgid="5279426047273930175">"সম্পন্ন হ\'ল"</string> + <string name="notification_done" msgid="5279426047273930175">"সম্পন্ন হ’ল"</string> <string name="inline_undo" msgid="558916737624706010">"আনডু কৰক"</string> <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string> <string name="notification_menu_gear_description" msgid="2204480013726775108">"জাননীৰ নিয়ন্ত্ৰণসমূহ"</string> @@ -783,8 +787,8 @@ <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ছেটিংসমূহ খোলক।"</string> <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"ক্ষিপ্ৰ ছেটিংসমূহ খোলক।"</string> <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"ক্ষিপ্ৰ ছেটিংসমূহ বন্ধ কৰক।"</string> - <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"এলার্ম ছেট কৰা হ\'ল।"</string> - <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> হিচাপে ছাইন ইন হ\'ল"</string> + <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"এলার্ম ছেট কৰা হ’ল।"</string> + <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> হিচাপে ছাইন ইন হ’ল"</string> <string name="data_connection_no_internet" msgid="4503302451650972989">"ইণ্টাৰনেট সংযোগ নাই"</string> <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"বিৱৰণসমূহ খোলক।"</string> <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>ৰ বাবে উপলব্ধ নহয়"</string> @@ -806,9 +810,9 @@ <string name="pip_skip_to_prev" msgid="1955311326688637914">"আগৰটো মিডিয়ালৈ যাওক"</string> <string name="thermal_shutdown_title" msgid="4458304833443861111">"আপোনাৰ ফ\'নটো গৰম হোৱাৰ কাৰণে অফ কৰা হৈছিল"</string> <string name="thermal_shutdown_message" msgid="9006456746902370523">"আপোনাৰ ফ\'নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে"</string> - <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"আপোনাৰ ফ\'নটো অত্যধিক গৰম হোৱাৰ বাবে ইয়াক ঠাণ্ডা কৰিবলৈ অফ কৰা হৈছিল। আপোনাৰ ফ\'নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\n\nআপোনাৰ ফ\'নটো গৰম হ\'ব পাৰে, যদিহে আপুনি:\n • ফ\'নটোৰ হাৰ্ডৱেৰ অত্যধিক মাত্ৰাত ব্যৱহাৰ কৰা এপসমূহ চলালে (যেনে, ভিডিঅ\' গেইম, ভিডিঅ\', দিক্-নিৰ্দেশনা এপসমূহ)\n • খুউব ডাঙৰ আকাৰৰ ফাইল আপল\'ড বা ডাউনল\'ড কৰিলে\n • আপোনাৰ ফ\'নটো উচ্চ তাপমাত্ৰাৰ পৰিৱেশত ব্যৱহাৰ কৰিলে"</string> + <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"আপোনাৰ ফ\'নটো অত্যধিক গৰম হোৱাৰ বাবে ইয়াক ঠাণ্ডা কৰিবলৈ অফ কৰা হৈছিল। আপোনাৰ ফ\'নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\n\nআপোনাৰ ফ\'নটো গৰম হ\'ব পাৰে, যদিহে আপুনি:\n • ফ\'নটোৰ হাৰ্ডৱেৰ অত্যধিক মাত্ৰাত ব্যৱহাৰ কৰা এপসমূহ চলালে (যেনে, ভিডিঅ\' গেইম, ভিডিঅ\', দিক্-নিৰ্দেশনা এপসমূহ)\n • খুউব ডাঙৰ আকাৰৰ ফাইল আপল\'ড বা ডাউনল’ড কৰিলে\n • আপোনাৰ ফ\'নটো উচ্চ তাপমাত্ৰাৰ পৰিৱেশত ব্যৱহাৰ কৰিলে"</string> <string name="high_temp_title" msgid="4589508026407318374">"ফ\'নটো গৰম হ\'বলৈ ধৰিছে"</string> - <string name="high_temp_notif_message" msgid="5642466103153429279">"ফ\'নটো ঠাণ্ডা হৈ থকা সময়ত কিছুমান সুবিধা উপলব্ধ নহ\'ব"</string> + <string name="high_temp_notif_message" msgid="5642466103153429279">"ফ\'নটো ঠাণ্ডা হৈ থকা সময়ত কিছুমান সুবিধা উপলব্ধ নহ’ব"</string> <string name="high_temp_dialog_message" msgid="6840700639374113553">"আপোনাৰ ফ\'নটোৱে নিজে নিজে ঠাণ্ডা হ\'বলৈ স্বয়ংক্ৰিয়ভাৱে চেষ্টা কৰিব। আপুনি ফ\'নটো ব্যৱহাৰ কৰি থাকিব পাৰে কিন্তু ই লাহে লাহে চলিব পাৰে।\n\nফ\'নটো সম্পূৰ্ণভাৱে ঠাণ্ডা হোৱাৰ পিছত ই আগৰ নিচিনাকৈয়েই চলিব।"</string> <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"বাওঁ শ্বৰ্টকাট"</string> <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"সোঁ শ্বৰ্টকাট"</string> @@ -836,7 +840,7 @@ <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ইনষ্ট\'ল নকৰাকৈয়েই এপটো খোলা হৈছে। অধিক জানিবলৈ টিপক।"</string> <string name="app_info" msgid="6856026610594615344">"এপ্ সম্পৰ্কীয় তথ্য"</string> <string name="go_to_web" msgid="2650669128861626071">"ব্ৰাউজাৰলৈ যাওক"</string> - <string name="mobile_data" msgid="7094582042819250762">"ম\'বাইল ডেটা"</string> + <string name="mobile_data" msgid="7094582042819250762">"ম’বাইল ডেটা"</string> <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="wifi_is_off" msgid="1838559392210456893">"ৱাই-ফাই অফ অৱস্থাত আছে"</string> <string name="bt_is_off" msgid="2640685272289706392">"ব্লুটুথ অফ অৱস্থাত আছে"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 9c2cbb96bdaa..907e19d787d2 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Rominq"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"İş rejimi yanılıdır."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Qənaəti deaktiv edildi."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Qənaəti aktiv edildi."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Məxfiliyi deaktivdir."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Məxfiliyi aktivdir."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Enerji yığır"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G məlumatlarına fasilə verildi"</string> @@ -884,4 +888,7 @@ <item quantity="other">Digər <xliff:g id="NUM_APPS_1">%d</xliff:g> tətbiq</item> <item quantity="one">Digər <xliff:g id="NUM_APPS_0">%d</xliff:g> tətbiq</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensorlar deaktivdir"</string> + <string name="device_services" msgid="1191212554435440592">"Cihaz Xidmətləri"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"Başlıq yoxdur"</string> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 13919bb75d78..8668c6baf9c8 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Režim rada je uključen."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ušteda podataka je isključena."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ušteda podataka je uključena."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Isključena je privatnost senzora."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Uključena je privatnost senzora."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Osvetljenost ekrana"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Puni se"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G podaci su pauzirani"</string> @@ -890,4 +894,7 @@ <item quantity="few">I još <xliff:g id="NUM_APPS_1">%d</xliff:g> aplikacije</item> <item quantity="other">I još <xliff:g id="NUM_APPS_1">%d</xliff:g> aplikacija</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori su isključeni"</string> + <string name="device_services" msgid="1191212554435440592">"Usluge za uređaje"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"Bez naslova"</string> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 2f2f5602b6f9..4cc91d2c9517 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роўмінг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -252,6 +254,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Рэжым працы ўключаны."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Эканомія трафіку адключана."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Эканомія трафіку ўключана."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Прыватнасць датчыкаў выключана."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Прыватнасць датчыкаў уключана."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Яркасць дысплэя"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Ідзе зарадка"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Перадача даных 2G-3G прыпынена"</string> @@ -898,4 +902,8 @@ <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> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Датчыкі выкл."</string> + <string name="device_services" msgid="1191212554435440592">"Сэрвісы прылады"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index d985976e4ad9..ede7af9a2084 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роуминг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Работният режим е включен."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Функцията „Икономия на данни“ е изключена."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Функцията „Икономия на данни“ е включена."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Настройката Sensor Privacy е изключена."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Настройката Sensor Privacy е включена."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Яркост на екрана"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Зарежда се"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Данните от 2G – 3G са поставени на пауза"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 504b3facb1d5..76a344f78893 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"রোমিং"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"কাজের মোড চালু আছে"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ডেটা সেভার বন্ধ আছে।"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ডেটা সেভার চালু আছে।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"সেন্সরের গোপনীয়তা বন্ধ আছে।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"সেন্সরের গোপনীয়তা চালু আছে।"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"প্রদর্শনের উজ্জ্বলতা"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"চার্জ হচ্ছে"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ডেটা বিরতি দেওয়া হয়েছে"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index cdb0c65d12aa..77429a0d074f 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Poslovni režim je uključen."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ušteda podataka je isključena."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ušteda podataka je uključena."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Privatnost senzora je isključena."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Privatnost senzora je uključena."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Osvjetljenje ekrana"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Punjenje"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G prijenos podataka je pauzirano"</string> @@ -892,4 +896,7 @@ <item quantity="few"><xliff:g id="NUM_APPS_1">%d</xliff:g> druge aplikacije</item> <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> drugih aplikacija</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori su isključeni"</string> + <string name="device_services" msgid="1191212554435440592">"Usluge uređaja"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"Bez naslova"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 16770dced872..69550b07de0b 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Itinerància"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"S\'ha activat el mode de feina."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"S\'ha desactivat l\'Economitzador de dades."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"S\'ha activat l\'Economitzador de dades."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"El sensor de privadesa està desactivat."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"El sensor de privadesa està activat."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Brillantor de la pantalla"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"S\'està carregant"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Les dades 2G-3G estan aturades"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 7d1976baf186..cf116e3211f7 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Pracovní režim je zapnutý."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Spořič dat byl vypnut."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Spořič dat byl zapnut."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Ochrana soukromí obsahu ze senzorů je vypnuta."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Ochrana soukromí obsahu ze senzorů je zapnuta."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Jas displeje"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Nabíjení"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G a 3G jsou pozastavena"</string> @@ -896,4 +900,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> dalších aplikací</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> dalších aplikací</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzory jsou vypnuty"</string> + <string name="device_services" msgid="1191212554435440592">"Služby zařízení"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 0a9ca2e1c631..ce9a8212dc00 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbejdstilstand er slået til."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Datasparefunktionen er slået fra."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Datasparefunktionen er slået til."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Privat sensortilstand blev deaktiveret."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Privat sensortilstand blev aktiveret."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Skærmens lysstyrke"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Oplader"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G-data er sat på pause"</string> @@ -884,4 +888,8 @@ <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> anden app</item> <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> andre apps</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Deaktiver sensorer"</string> + <string name="device_services" msgid="1191212554435440592">"Enhedstjenester"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 23336de5218f..447f8b9b840c 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -254,6 +256,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbeitsmodus aktiviert."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Der Datensparmodus ist deaktiviert."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Der Datensparmodus ist aktiviert."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy deaktiviert."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy aktiviert."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Helligkeit des Displays"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Wird aufgeladen"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-/3G-Daten pausiert"</string> @@ -888,4 +892,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 48f6d367262a..7468b3a9bcce 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Περιαγωγή"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Η λειτουργία εργασίας ενεργοποιήθηκε."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Η Εξοικονόμηση δεδομένων είναι ανενεργή."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Η Εξοικονόμηση δεδομένων είναι ενεργή."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Το απόρρητο του αισθητήρα είναι ανενεργό."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Το απόρρητο του αισθητήρα είναι ενεργό."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Φωτεινότητα οθόνης"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Φόρτιση"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Τα δεδομένα 2G-3G τέθηκαν σε παύση"</string> @@ -884,4 +888,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index c9a984bfa83f..5e2fb036b04b 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy turned off."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Charging"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> other apps</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> other app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> + <string name="device_services" msgid="1191212554435440592">"Device Services"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index effbb0b862f3..38915694b3a4 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy turned off."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Charging"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> other apps</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> other app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> + <string name="device_services" msgid="1191212554435440592">"Device Services"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index c9a984bfa83f..5e2fb036b04b 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy turned off."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Charging"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> other apps</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> other app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> + <string name="device_services" msgid="1191212554435440592">"Device Services"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index c9a984bfa83f..5e2fb036b04b 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy turned off."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Charging"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> other apps</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> other app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> + <string name="device_services" msgid="1191212554435440592">"Device Services"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 094aa51ed3ff..d53d61bbf7a4 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -166,6 +166,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -249,6 +251,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy turned off."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Charging"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> @@ -884,4 +888,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> other apps</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> other app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> + <string name="device_services" msgid="1191212554435440592">"Device Services"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"No title"</string> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 4d44e0d279e8..9ef6a83b0754 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Se activó el modo de trabajo."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Se desactivó el Ahorro de datos."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Se activó el Ahorro de datos."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Se desactivó el modo de privacidad del sensor."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Se activó el modo de privacidad del sensor."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Brillo de pantalla"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Cargando"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Datos 2G-3G pausados"</string> @@ -884,4 +888,9 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> apps más</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> app más</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Se desactivaron los sensores"</string> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 9c0919690f65..f4e107ddfa4e 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Itinerancia"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modo de trabajo activado."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ahorro de datos desactivado."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ahorro de datos activado."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Se ha desactivado el sensor de privacidad."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Se ha activado el sensor de privacidad."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Brillo de la pantalla"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Cargando"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Datos 2G-3G pausados"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 8c755b9889c7..d8568df45ce0 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Rändlus"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Töörežiim on sisse lülitatud."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Andmeside mahu säästja on välja lülitatud."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Andmeside mahu säästja on sisse lülitatud."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Andur Privaatsus on välja lülitatud."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Andur Privaatsus on sisse lülitatud."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ekraani heledus"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Laadimine"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G andmekasutus on peatatud"</string> @@ -884,4 +888,8 @@ <item quantity="other">Veel <xliff:g id="NUM_APPS_1">%d</xliff:g> rakendust</item> <item quantity="one">Veel <xliff:g id="NUM_APPS_0">%d</xliff:g> rakendus</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Andurid on välja lülitatud"</string> + <string name="device_services" msgid="1191212554435440592">"Seadme teenused"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 51a7935e06c4..cfdf7a580e9c 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Ibiltaritza"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Aktibatuta dago lan modua."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Desaktibatuta dago datu-aurrezlea."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Aktibatuta dago datu-aurrezlea."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Desaktibatu da sentsoreen pribatutasuna."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Aktibatu da sentsoreen pribatutasuna."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Bistaratu distira"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Kargatzen"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G datuen erabilera eten da"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index e31a07b1b0f9..e89f90629988 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"رومینگ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"حالت کار روشن شد."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"صرفهجویی داده خاموش شد."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"صرفهجویی داده روشن شد."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"«حریم خصوصی حسگر» خاموش است."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"«حریم خصوصی حسگر» روشن است."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"روشنایی نمایشگر"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"درحال شارژ شدن"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"داده 2G-3G موقتاً متوقف شده است"</string> @@ -884,4 +888,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index d4e59aed2742..cd92d45cb721 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Työtila otettiin käyttöön."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver poistettiin käytöstä."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver otettiin käyttöön."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Anturien yksityisyystila ei käytössä"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Anturien yksityisyystila käytössä"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Näytön kirkkaus"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Ladataan"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G-tiedonsiirto keskeytettiin"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> muuta sovellusta</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> muu sovellus</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Anturit pois päältä"</string> + <string name="device_services" msgid="1191212554435440592">"Laitepalvelut"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 31cc6d3791c1..695a6a561466 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Itinérance"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Le mode Travail est activé."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Mode Économiseur de données désactivé."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Mode Économiseur de données activé."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"La confidentialité des capteurs est désactivée."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"La confidentialité des capteurs est désactivée."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Luminosité de l\'écran"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"En cours de charge"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Données 2G/3G désactivées"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index db6ffd932b06..a1a0352a89e7 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Itinérance"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Le mode Travail est activé."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"L\'économiseur de données est désactivé."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"L\'économiseur de données est activé."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Confidentialité des capteurs désactivée."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Confidentialité des capteurs activée."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Luminosité de l\'affichage"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"En charge…"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Données 2G-3G désactivées"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 5dccba3ca2ba..7f111e8ca4ed 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Itinerancia"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Activouse o modo de traballo."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Desactivouse o Economizador de datos."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Activouse o Economizador de datos."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Desactivouse a privacidade dos sensores."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Activouse a privacidade dos sensores."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Brillo de pantalla"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Cargando"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os datos 2G-3G están en pausa"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> aplicacións máis</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplicación máis</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Desactivar sensores"</string> + <string name="device_services" msgid="1191212554435440592">"Servizos do dispositivo"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 1e6e733898d7..8525094cc1df 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"રોમિંગ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"કાર્ય મોડ ચાલુ કર્યો."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ડેટા સેવર બંધ કર્યું."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ડેટા સેવર ચાલુ કર્યું."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"સેન્સર પ્રાઇવસી બંધ કરવામાં આવી છે."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"સેન્સર પ્રાઇવસી ચાલુ કરવામાં આવી છે."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"પ્રદર્શન તેજ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ચાર્જ થઈ રહ્યું છે"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ડેટા થોભાવ્યો છે"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 57709aa55168..1c6991049b1f 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"एलटीई"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"रोमिंग"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"कार्य मोड चालू किया गया."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा बचाने की सेटिंग बंद कर दी गई है."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा बचाने की सेटिंग चालू कर दी गई है."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"सेंसर निजता को बंद कर दिया गया है."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"सेंसर निजता को चालू कर दिया गया है."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"स्क्रीन की स्क्रीन की रोशनी"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"चार्ज हो रही है"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटा रोक दिया गया है"</string> @@ -599,7 +603,7 @@ <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"चालू"</string> <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string> <string name="power_notification_controls_description" msgid="4372459941671353358">"पावर सूचना नियंत्रण के ज़रिये, आप किसी ऐप की सूचना को उसकी अहमियत के हिसाब से 0 से 5 के लेवल पर सेट कर सकते हैं.\n\n"<b>"लेवल 5"</b>" \n- सूचना सूची में सबसे ऊपर दिखाएं \n- पूरे स्क्रीन को ढंकने की अनुमति दें \n- लगातार देखते रहें \n\n"<b>" लेवल 4"</b>" \n- पूरे स्क्रीन को ढंकें \n- लगातार देखते रहें \n\n"<b>"लेवल 3"</b>" \n- पूरे स्क्रीन को ढंकने से रोकें \n-कभी भी न देखें \n\n"<b>"लेवल 2"</b>" \n- पूरे स्क्रीन को ढंकने से रोकें \n- कभी भी देखें \n- कभी भी आवाज़ या कंपन (वाइब्रेशन) न करें \n\n"<b>"लेवल 1"</b>" \n- पूरे स्क्रीन को ढंकने से रोकें \n- कभी भी न देखें \n- कभी भी आवाज़ या कंपन (वाइब्रेशन) न करें \n- लॉक स्क्रीन और स्टेटस बार से छिपाएं \n- सूचना सूची के नीचे दिखाएं \n\n"<b>"लेवल 0"</b>" \n- ऐप्लिकेशन की सभी सूचनाएं रोक दें"</string> - <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string> + <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचनाएं"</string> <string name="notification_channel_disabled" msgid="344536703863700565">"अब आपको ये सूचनाएं दिखाई नहीं देंगी"</string> <string name="notification_channel_minimized" msgid="1664411570378910931">"इन सूचनाओं को छोटा कर दिया जाएगा"</string> <string name="notification_channel_silenced" msgid="2877199534497961942">"ये सूचनाएं बिना आवाज़ के दिखाई जाएंगी"</string> @@ -834,7 +838,7 @@ <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> चल रहा है"</string> <string name="instant_apps_message" msgid="1183313016396018086">"ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है."</string> <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है. ज़्यादा जानने के लिए टैप करें."</string> - <string name="app_info" msgid="6856026610594615344">"ऐप की जानकारी"</string> + <string name="app_info" msgid="6856026610594615344">"ऐप्लिकेशन की जानकारी"</string> <string name="go_to_web" msgid="2650669128861626071">"ब्राउज़र पर जाएं"</string> <string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string> <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string> @@ -884,4 +888,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 40d9932df4a7..8f3a11b63ec9 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G i više"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Način rada uključen."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Štednja podatkovnog prometa isključena."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Štednja podatkovnog prometa uključena."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Isključena je privatnost senzora."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Uključena je privatnost senzora."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Svjetlina zaslona"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Punjenje"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G – 3G podaci pauzirani"</string> @@ -890,4 +894,7 @@ <item quantity="few">Još <xliff:g id="NUM_APPS_1">%d</xliff:g> aplikacije</item> <item quantity="other">Još <xliff:g id="NUM_APPS_1">%d</xliff:g> aplikacija</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori su isključeni"</string> + <string name="device_services" msgid="1191212554435440592">"Usluge uređaja"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"Bez naslova"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index e1cdc0be578c..ae12412a6cf0 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Barangolás"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Munka mód bekapcsolva."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Adatforgalom-csökkentő kikapcsolva."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Adatforgalom-csökkentő bekapcsolva."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Kikapcsolta a Szenzoradatok védelmét."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Bekapcsolta a Szenzoradatok védelmét."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"A kijelző fényereje"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Töltés folyamatban…"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"A 2G és 3G adatforgalom szünetel."</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> további alkalmazás</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> további alkalmazás</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Érzékelők kikapcsolva"</string> + <string name="device_services" msgid="1191212554435440592">"Eszközszolgáltatások"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index f5921dc2d7ef..ffcc762ccfa1 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Ռոումինգ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Աշխատանքային ռեժիմը միացվեց:"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Տվյալների խնայումն անջատվեց:"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Թրաֆիկի տնտեսումը միացվեց:"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Տվիչների գաղտնիությունն անջատած է:"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Տվիչների գաղտնիությունը միացված է:"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ցուցադրել պայծառությունը"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Լիցքավորում"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2Գ-3Գ տվյալների օգտագործումը դադարեցված է"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 06609e3363da..eb99a6cc698c 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Mode kerja diaktifkan."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Penghemat Kuota nonaktif."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Penghemat Kuota diaktifkan."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Privasi Sensor dinonaktifkan."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Privasi Sensor diaktifkan."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Kecerahan tampilan"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Mengisi daya"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G-3G dijeda"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> aplikasi lain</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplikasi lain</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensor nonaktif"</string> + <string name="device_services" msgid="1191212554435440592">"Layanan Perangkat"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 83c75e462453..0040c3c723a7 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Reiki"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Kveikt á vinnustillingu."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Slökkt var á gagnasparnaði."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Kveikt var á gagnasparnaði."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Slökkt á persónvuernd skynjara."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Kveikt á persónuvernd fyrir skynjara."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Birtustig skjás"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Í hleðslu"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Slökkt er á 2G- og 3G-gögnum"</string> @@ -884,4 +888,8 @@ <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> forrit í viðbót</item> <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> forrit í viðbót</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Slökkt á skynjurum"</string> + <string name="device_services" msgid="1191212554435440592">"Tækjaþjónusta"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 4c512fe63176..83956e83f90d 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modalità Lavoro attivata."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Funzione Risparmio dati disattivata."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Funzione Risparmio dati attivata."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Privacy per i sensori disattivata."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Privacy per i sensori attiva."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Luminosità dello schermo"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"In carica"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dati 2G-3G sospesi"</string> @@ -884,4 +888,8 @@ <item quantity="other">Altre <xliff:g id="NUM_APPS_1">%d</xliff:g> app</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> altra app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensori disattivati"</string> + <string name="device_services" msgid="1191212554435440592">"Servizi del dispositivo"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 37fb1f713072..d43551d214a8 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"+4G"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"+LTE"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"+G5"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"נדידה"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"מצב עבודה הופעל."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"חוסך הנתונים (Data Saver) כובה."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"חוסך הנתונים (Data Saver) הופעל."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"התכונה \'פרטיות חיישנים\' כבויה."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"התכונה \'פרטיות חיישנים\' פועלת."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"בהירות תצוגה"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"הסוללה נטענת"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"השימוש בנתוני 2G-3G מושהה"</string> @@ -896,4 +900,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 519d333fe8fa..f7d52ed16c50 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ローミング"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work モードをオンにしました。"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"データセーバーが OFF になりました。"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"データセーバーが ON になりました。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"センサー プライバシーを OFF にしました。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"センサー プライバシーを ON にしました。"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ディスプレイの明るさ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"充電しています"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G~3Gデータは一時停止中です"</string> @@ -884,4 +888,8 @@ <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">"センサー OFF"</string> + <string name="device_services" msgid="1191212554435440592">"デバイス サービス"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 50a25bd4f3b4..e1ee20eb12ba 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"როუმინგი"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"სამსახურის რეჟიმი ჩართულია."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"მონაცემთა დამზოგველი გამორთულია."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"მონაცემთა დამზოგველი ჩართულია."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"სენსორების კონფიდენციალურობა გამორთულია."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"სენსორების კონფიდენციალურობა ჩართულია."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ეკრანის სიკაშკაშე"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"იტენება"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G მონაცემები შეჩერებულია"</string> @@ -884,4 +888,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index b7e02a22e807..a1788fcb551d 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роуминг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Жұмыс режимі қосылды."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Трафикті үнемдеу функциясы өшірілді."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Трафикті үнемдеу функциясы қосылды."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy функциясы өшірулі."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy функциясы қосулы."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Дисплей жарықтығы"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Зарядтау"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G деректері кідіртілді"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 1330f3683f74..0cbd06c1d89e 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"រ៉ូមីង"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"បានបើករបៀបការងារ"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"បានបិទកម្មវិធីសន្សំសំចៃទិន្នន័យ"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"បានបើកកម្មវិធីសន្សំសំចៃទិន្នន័យ"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"បានបិទឯកជនភាពឧបករណ៍ចាប់សញ្ញា។"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"បានបើកឯកជនភាពឧបករណ៍ចាប់សញ្ញា។"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ពន្លឺការបង្ហាញ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"កំពុងសាកថ្ម"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"ទិន្នន័យ 2G-3G ត្រូវបានផ្អាក"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 58d2fb80aa08..9f46742928dc 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ರೋಮಿಂಗ್"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"ಕೆಲಸದ ಮೋಡ್ ಆನ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ಡೇಟಾ ಸೇವರ್ ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ಡೇಟಾ ಸೇವರ್ ಆನ್ ಮಾಡಲಾಗಿದೆ."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"ಸೆನ್ಸರ್ ಗೌಪ್ಯತೆ ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"ಸೆನ್ಸರ್ ಗೌಪ್ಯತೆ ಆನ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ಹೊಳಪನ್ನು ಪ್ರದರ್ಶಿಸಿ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ಡೇಟಾವನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 76fcaf5b22a2..581ffa9cb1f4 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G 이상"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"로밍"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"작업 모드가 사용 설정되었습니다."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"데이터 절약 모드를 사용 중지했습니다."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"데이터 절약 모드를 사용 설정했습니다."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"센서 개인정보 보호가 사용 중지되었습니다."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"센서 개인정보 보호가 사용 설정되었습니다."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"디스플레이 밝기"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"충전 중"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G 데이터 사용 중지됨"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 54f8da33970e..ba5a0ace7d69 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роуминг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Иштөө режими күйгүзүлдү."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Трафикти үнөмдөө режими өчүрүлдү."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Трафикти үнөмдөө режими күйгүзүлдү."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Сенсордун купуялыгы өчүрүлдү."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Сенсордун купуялыгы күйгүзүлдү."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Жарыктыгын көрсөтүү"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Кубатталууда"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G дайындары тындырылды."</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 8cc18e91c1a6..a4ffffb4ea30 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ໂຣມມິງ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"ໂໝດການເຮັດວຽກເປີດຢູ່."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ປິດຕົວປະຢັດອິນເຕີເນັດແລ້ວ."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ເປີດຕົວປະຢັດອິນເຕີເນັດແລ້ວ."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"ປິດການຮັບຮູ້ຄວາມເປັນສ່ວນຕົວແລ້ວ."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"ເປີດການຮັບຮູ້ຄວາມເປັນສ່ວນຕົວແລ້ວ."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ຄວາມແຈ້ງຂອງຈໍ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ກຳລັງສາກໄຟ"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"ຂໍ້ມູນ 2G-3G ຢຸດຊົ່ວຄາວແລ້ວ"</string> @@ -884,4 +888,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index e8d6438d6a0f..46cd3f070f8c 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Tarptinklinis ryšys"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Darbo režimas įjungtas."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Duomenų taupymo priemonė išjungta."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Duomenų taupymo priemonė įjungta."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Jutiklių privatumo funkcija išjungta."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Jutiklių privatumo funkcija įjungta."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ekrano šviesumas"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Įkrovimas"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G duomenys pristabdyti"</string> @@ -896,4 +900,9 @@ <item quantity="many">Dar <xliff:g id="NUM_APPS_1">%d</xliff:g> programos</item> <item quantity="other">Dar <xliff:g id="NUM_APPS_1">%d</xliff:g> programų</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Jutikliai išjungti"</string> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 4c6282dd5029..a1203d503401 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Viesabonēšana"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Darba režīms ir ieslēgts."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Datu lietojuma samazinātājs ir izslēgts."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Datu lietojuma samazinātājs ir ieslēgts."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensoru konfidencialitāte ir izslēgta."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensoru konfidencialitāte ir ieslēgta."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ekrāna spilgtums"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Notiek uzlāde"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G datu lietojums ir apturēts"</string> @@ -890,4 +894,8 @@ <item quantity="one">Vēl <xliff:g id="NUM_APPS_1">%d</xliff:g> lietotne</item> <item quantity="other">Vēl <xliff:g id="NUM_APPS_1">%d</xliff:g> lietotnes</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensori izslēgti"</string> + <string name="device_services" msgid="1191212554435440592">"Ierīces pakalpojumi"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 8591932caf42..a3fd2d5fb8bd 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роаминг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Режимот на работа е вклучен."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Штедачот на интернет е исклучен."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Штедачот на интернет е вклучен."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Сензорот „Приватност“ е исклучен."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Сензорот „Приватност“ е вклучен."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Осветленост на екранот"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Се полни"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Податоците 2G-3G се паузирани"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 51ebb2e134c6..f3075b8cc5dd 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"റോമിംഗ്"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDG"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"പ്രവർത്തന മോഡ് ഓണാക്കി."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ഡാറ്റ സേവർ ഓഫാക്കി."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ഡാറ്റ സേവർ ഓണാക്കി."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"സെൻസർ സ്വകാര്യത ഓഫാക്കി."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"സെൻസർ സ്വകാര്യത ഓഫാണ്."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ഡിസ്പ്ലേ തെളിച്ചം"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ചാർജ്ജുചെയ്യുന്നു"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ഡാറ്റ താൽക്കാലികമായി നിർത്തി"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 6be0e713efdd..723689365fe3 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роуминг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Ажлын горимыг асаасан."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Дата хэмнэгчийг унтраасан."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Дата хэмнэгчийг асаасан."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Мэдрэгчийн нууцлалыг унтраасан."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Мэдрэгчийн нууцлалыг асаасан."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Дэлгэцийн гэрэлтэлт"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Цэнэглэж байна"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G дата-г түр зогсоосон байна"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 6fb44ccf0e07..59e481ccc6fc 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"४G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"१X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"रोमिंग"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"कार्य मोड चालू केला."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा सर्व्हर बंद केला."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा सर्व्हर चालू केला."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"सेन्सर गोपनीयता बंद केली आहे."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"सेन्सर गोपनीयता सुरू केली आहे."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"डिस्प्ले चमक"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"चार्ज होत आहे"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटास विराम दिला आहे"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 58a417d364b9..e77771d23508 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Perayauan"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Mod kerja dihidupkan."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Penjimat Data dimatikan."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Penjimat Data dihidupkan."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Privasi penderia dimatikan."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Privasi penderia dihidupkan."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Kecerahan paparan"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Mengecas"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G-3G dijeda"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> apl lain</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g>apl lain</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Penderia dimatikan"</string> + <string name="device_services" msgid="1191212554435440592">"Perkhidmatan Peranti"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index aa52f7b8d672..e5561e81daf6 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်ခြင်း"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"အလုပ် မုဒ်ကို ဖွင့်ထားပါသည်။"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ဒေတာချွေတာမှု ပိတ်ထားသည်။"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ဒေတာချွေတာမှု ဖွင့်ထားသည်။"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"\'အာရုံခံကိရိယာ ကန့်သတ်ရန်ဆက်တင်\' ကို ပိတ်ထားသည်။"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"\'အာရုံခံကိရိယာ ကန့်သတ်ရန်ဆက်တင်\' ကို ဖွင့်ထားသည်။"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"တောက်ပမှုကို ပြရန်"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"အားသွင်းနေသည်"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ဒေတာ ခေတ္တရပ်တန့်သည်"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 558fd9b7382d..a1a12bdfacee 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbeidsmodusen er slått på."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Datasparing er slått av."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Datasparing er slått på."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy er slått av."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy er slått på."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Lysstyrken på skjermen"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Lader"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G- og 3G-data er satt på pause"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> andre apper</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> annen app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensorer er av"</string> + <string name="device_services" msgid="1191212554435440592">"Enhetstjenester"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index b82642067132..096db56c74ad 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"रोमिङ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"कार्य मोड सक्रिय भयो।"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा सेभरलाई निष्क्रिय पारियो।"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा सेभरलाई सक्रिय गरियो।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"सेन्सरको गोपनियता निष्क्रिय पारिएको छ।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"सेन्सरको गोपनियता सक्रिय गरिएको छ।"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"प्रदर्शन चमक"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"चार्ज गर्दै"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटा रोकिएको छ"</string> @@ -431,7 +435,7 @@ <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="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले आफ्नो स्क्रीनमा प्रदर्शित हुने सबै खिच्न शुरू गर्नेछ।"</string> + <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले आफ्नो स्क्रीनमा प्रदर्शित हुने सबै खिच्न शुरू गर्ने छ।"</string> <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> @@ -700,7 +704,7 @@ <string name="tuner_full_zen_title" msgid="4540823317772234308">"भोल्युम नियन्त्रणसहित देखाउनुहोस्"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"बाधा नपुर्याउनुहोस्"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"भोल्युम बटनका सर्टकट"</string> - <string name="volume_up_silent" msgid="7141255269783588286">"भोल्युम बढाउनेमा बाधा नपुर्याउनुहोस् प्रविष्ट गर्नुहोस्"</string> + <string name="volume_up_silent" msgid="7141255269783588286">"भोल्युम बढाउनेमा बाधा नपुर्याउनुहोस् प्रविष्टि गर्नुहोस्"</string> <string name="battery" msgid="7498329822413202973">"ब्याट्री"</string> <string name="clock" msgid="7416090374234785905">"घडी"</string> <string name="headset" msgid="4534219457597457353">"हेडसेट"</string> @@ -809,7 +813,7 @@ <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n • धेरै संसाधन खपत गर्ने अनुप्रयोगहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन अनुप्रयोगहरू)\n • ठूला फाइलहरूको डाउनलोड वा अपलोड\n • उच्च तापक्रममा फोनको प्रयोग"</string> <string name="high_temp_title" msgid="4589508026407318374">"फोन तातो भइरहेको छ"</string> <string name="high_temp_notif_message" msgid="5642466103153429279">"फोन चिसो हुँदै गर्दा केही विशेषताहरूलाई सीमित गरिन्छ"</string> - <string name="high_temp_dialog_message" msgid="6840700639374113553">"तपाईंको फोन स्वतः चिसो हुने प्रयास गर्नेछ। तपाईं अझै पनि आफ्नो फोनको प्रयोग गर्न सक्नुहुन्छ तर त्यो अझ ढिलो चल्न सक्छ।\n\nचिसो भएपछि तपाईंको फोन सामान्य गतिमा चल्नेछ।"</string> + <string name="high_temp_dialog_message" msgid="6840700639374113553">"तपाईंको फोन स्वतः चिसो हुने प्रयास गर्ने छ। तपाईं अझै पनि आफ्नो फोनको प्रयोग गर्न सक्नुहुन्छ तर त्यो अझ ढिलो चल्न सक्छ।\n\nचिसो भएपछि तपाईंको फोन सामान्य गतिमा चल्नेछ।"</string> <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"बायाँतिरको सर्टकट"</string> <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"दायाँतिरको सर्टकट"</string> <string name="lockscreen_unlock_left" msgid="2043092136246951985">"बायाँतिरको सर्टकटले पनि अनलक गर्छ"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 06467b85a687..3607ff8fff59 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Werkmodus ingeschakeld."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Databesparing is uitgeschakeld."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Databesparing is ingeschakeld."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensorprivacy uitgeschakeld."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensorprivacy ingeschakeld."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Helderheid van het scherm"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Opladen"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G/3G-data zijn onderbroken"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> andere apps</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> andere app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensoren uit"</string> + <string name="device_services" msgid="1191212554435440592">"Apparaatservices"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index de7f3b2317a7..5cb98eeae88c 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ରୋମିଙ୍ଗ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"ୱର୍କ ମୋଡ୍କୁ ଅନ୍ କରାଯାଇଛି।"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ଡାଟା ସେଭର୍ ଅଫ୍ କରାଗଲା।"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ଡାଟା ସେଭର୍ ଅନ୍ କରାଗଲା।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"ସେନ୍ସର୍ ଗୋପନୀୟତାକୁ ବନ୍ଦ କରିଦିଆଯାଇଛି।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"ସେନ୍ସର୍ ଗୋପନୀୟତାକୁ ଚାଲୁ କରାଯାଇଛି।"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ଡିସ୍ପ୍ଲେ ଉଜ୍ଜ୍ୱଳତା"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ଚାର୍ଜ କରାଯାଉଛି"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ଡାଟା ପଜ୍ କରାଯାଇଛି"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 7883bbd0c55a..3702e2bb8ddf 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ਰੋਮਿੰਗ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"ਕੰਮ ਮੋਡ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ਡਾਟਾ ਸੇਵਰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"ਸੈਂਸਰ ਪਰਦੇਦਾਰੀ ਬੰਦ ਹੈ।"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"ਸੈਂਸਰ ਪਰਦੇਦਾਰੀ ਚਾਲੂ ਹੈ।"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ਡਿਸਪਲੇ ਚਮਕ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ਡਾਟਾ ਰੁਕ ਗਿਆ ਹੈ"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 81c26890f009..4ece82c79e29 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Tryb pracy włączony."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Oszczędzanie danych jest wyłączone."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Oszczędzanie danych jest włączone."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Wyłączono ustawienia prywatności czujników."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Włączono ustawienia prywatności czujników."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Jasność wyświetlacza"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Ładowanie"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Transmisja danych 2G-3G została wstrzymana"</string> @@ -896,4 +900,9 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> inne aplikacje</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> inna aplikacja</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Wyłącz czujniki"</string> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 05fcfb8d5df0..ac6991774daa 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modo de trabalho ativado."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Economia de dados desativada."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Economia de dados ativada."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor de privacidade desativado."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor de privacidade ativado."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Brilho da tela"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Carregando"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os dados 2G e 3G foram pausados"</string> @@ -884,4 +888,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> outro app</item> <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> outros apps</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> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index fafdad0d3759..375f5e8f94d2 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"O modo de trabalho foi ativado."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Poupança de dados desativada."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Poupança de dados ativada."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacidade desativado."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacidade ativado."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Brilho do visor"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"A carregar…"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dados 2G-3G em pausa"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 05fcfb8d5df0..ac6991774daa 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modo de trabalho ativado."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Economia de dados desativada."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Economia de dados ativada."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor de privacidade desativado."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor de privacidade ativado."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Brilho da tela"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Carregando"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os dados 2G e 3G foram pausados"</string> @@ -884,4 +888,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> outro app</item> <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> outros apps</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> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index cb9b5740df48..24254f67eccd 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modul de lucru a fost activat."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Economizorul de date a fost dezactivat."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Economizorul de date a fost activat."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Confidențialitatea senzorilor este dezactivată."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Confidențialitatea senzorilor este activată."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Luminozitatea ecranului"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Se încarcă"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Conexiunea de date 2G – 3G este întreruptă"</string> @@ -890,4 +894,8 @@ <item quantity="other">Alte <xliff:g id="NUM_APPS_1">%d</xliff:g> de aplicații</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> altă aplicație</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori dezactivați"</string> + <string name="device_services" msgid="1191212554435440592">"Servicii pentru dispozitiv"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index f9de77c751c4..a5d40598047b 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роуминг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Рабочий режим включен."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Режим экономии трафика отключен."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Режим экономии трафика включен."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Функция Sensor Privacy отключена."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Функция Sensor Privacy включена."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Яркость экрана"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Зарядка батареи"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Передача данных 2G и 3G приостановлена"</string> @@ -896,4 +900,8 @@ <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> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Датчики отключены"</string> + <string name="device_services" msgid="1191212554435440592">"Сервисы устройства"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index cd24df62b60d..cb22f3d431a2 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"රෝමිං"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"වැඩ ප්රකාරය ක්රියාත්මක කරන ලදී."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"දත්ත සුරැකුම ක්රියාවිරහිත කරන ලදී."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"දත්ත සුරැකුම ක්රියාත්මක කරන ලදී."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"සංවේදක රහස්යතාව ක්රියාවිරහිතයි."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"සංවේදක රහස්යතාව ක්රියාත්මකයි."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"සංදර්ශක දීප්තිය"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ආරෝපණය වෙමින්"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G දත්ත විරාම කර ඇත"</string> @@ -884,4 +888,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 941e9c7a0839..d9ba8de2240f 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Pracovný režim je zapnutý."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Šetrič dát bol vypnutý."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Šetrič dát bol zapnutý."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Senzor ochrany súkromia je vypnutý."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Senzor ochrany súkromia je zapnutý."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Jas displeja"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Nabíja sa"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dátové prenosy 2G a 3G sú pozastavené"</string> @@ -896,4 +900,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index e5555c7828ad..50482272c0c1 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Gostovanje"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Način za delo je vklopljen."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Varčevanje s podatki je izklopljeno."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Varčevanje s podatki je vklopljeno."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Zasebnost tipal je izklopljena."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Zasebnost tipal je vklopljena."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Svetlost zaslona"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Polnjenje"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Prenos podatkov v omrežju 2G/3G je zaustavljen"</string> @@ -896,4 +900,8 @@ <item quantity="few">in še <xliff:g id="NUM_APPS_1">%d</xliff:g> aplikacije</item> <item quantity="other">in še <xliff:g id="NUM_APPS_1">%d</xliff:g> aplikacij</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Izklop za tipala"</string> + <string name="device_services" msgid="1191212554435440592">"Storitve naprave"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index ba1f117007ec..66a577811bf5 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modaliteti i punës është i aktivizuar."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Kursyesi i të dhënave është çaktivizuar."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Kursyesi i të dhënave është aktivizuar."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Privatësia e sensorëve është çaktivizuar."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Privatësia e sensorëve është aktivizuar."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ndriçimi i ekranit"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Po ngarkohet"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Të dhënat 2G-3G janë ndërprerë"</string> @@ -884,4 +888,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> aplikacione të tjera</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> aplikacion tjetër</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensorët joaktivë"</string> + <string name="device_services" msgid="1191212554435440592">"Shërbimet e pajisjes"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"Pa titull"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 64dd9a45b9a1..1ff65d782fc0 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роминг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Режим рада је укључен."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Уштеда података је искључена."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Уштеда података је укључена."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Искључена је приватност сензора."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Укључена је приватност сензора."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Осветљеност екрана"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Пуни се"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G подаци су паузирани"</string> @@ -890,4 +894,7 @@ <item quantity="few">И још <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> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index dd3af059e1ca..22ffa812d3e9 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbetsläget har aktiverats."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Databesparing har inaktiverats."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Databesparing har aktiverats."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensorsekretess har inaktiverats."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensorsekretess har aktiverats."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Skärmens ljusstyrka"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Laddas"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G- och 3G-data har pausats"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> andra appar</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> annan app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensorer har inaktiverats"</string> + <string name="device_services" msgid="1191212554435440592">"Enhetstjänster"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 517009543a7c..69b3be7ffbc4 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Mitandao ya ng\'ambo"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Hali ya kazi imewashwa."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Kiokoa Data kimezimwa."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Kiokoa Data kimewashwa."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Umezima mipangilio ya Faragha ya Vitambuzi."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Umewasha mipangilio ya Faragha ya Vitambuzi."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ung\'aavu wa skrini"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Inachaji"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data ya 2G-3G imesitishwa"</string> @@ -884,4 +888,7 @@ <item quantity="other">Programu zingine <xliff:g id="NUM_APPS_1">%d</xliff:g></item> <item quantity="one">Programu nyingine <xliff:g id="NUM_APPS_0">%d</xliff:g></item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Umezima vitambuzi"</string> + <string name="device_services" msgid="1191212554435440592">"Huduma za Kifaa"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"Wimbo hauna jina"</string> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 9f3d7ca200d8..a35c78c9da6a 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"ரோமிங்"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"பணிப் பயன்முறை இயக்கப்பட்டது."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"டேட்டா சேமிப்பான் முடக்கப்பட்டது."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"டேட்டா சேமிப்பான் இயக்கப்பட்டது."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"\'சென்சார் தனியுரிமை\' ஆஃப் செய்யப்பட்டது."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"’சென்சார் தனியுரிமை’ ஆன் செய்யப்பட்டது."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"திரை பிரகாசம்"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"சார்ஜ் ஆகிறது"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G டேட்டா இடைநிறுத்தப்பட்டது"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 318410754750..e7eafbe7595b 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"రోమింగ్"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"పని మోడ్ ఆన్ చేయబడింది."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"డేటా సేవర్ ఆఫ్ చేయబడింది."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"డేటా సేవర్ ఆన్ చేయబడింది."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"సెన్సార్ గోప్యత ఆఫ్ చేయబడింది."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"సెన్సార్ గోప్యత ఆన్ చేయబడింది."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ప్రదర్శన ప్రకాశం"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"ఛార్జ్ అవుతోంది"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G డేటా పాజ్ చేయబడింది"</string> @@ -884,4 +888,9 @@ <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> + <!-- no translation found for device_services (1191212554435440592) --> + <skip /> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index bf3b1314f8eb..05df7bd2aa06 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"โรมมิ่ง"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"เปิดโหมดการทำงานแล้ว"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ปิดโปรแกรมประหยัดอินเทอร์เน็ตแล้ว"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"เปิดโปรแกรมประหยัดอินเทอร์เน็ตแล้ว"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"ปิดความเป็นส่วนตัวสำหรับเซ็นเซอร์แล้ว"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"เปิดความเป็นส่วนตัวสำหรับเซ็นเซอร์แล้ว"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ความสว่างของหน้าจอ"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"กำลังชาร์จ"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"หยุดการใช้ข้อมูล 2G-3G ชั่วคราวแล้ว"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index fcfd1cd119fa..3bd6ea6708dd 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Roaming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Na-on ang work mode."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Na-off ang Data Saver."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Na-on ang Data Saver."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Naka-off ang Privacy ng Sensor."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Naka-on ang Privacy ng Sensor."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Liwanag ng display"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Nagcha-charge"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Naka-pause ang 2G-3G data"</string> @@ -884,4 +888,8 @@ <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> (na) iba pang app</item> <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> (na) iba pang app</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Naka-off ang mga sensor"</string> + <string name="device_services" msgid="1191212554435440592">"Mga Serbisyo ng Device"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index c8368751de70..4962b167b5d0 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Dolaşım"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Çalışma modu açıldı."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Veri Tasarrufu kapatıldı."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Veri Tasarrufu açıldı."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensör Gizliliği kapatıldı."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensör Gizliliği açıldı."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ekran parlaklığı"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Şarj oluyor"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G veri kullanımı duraklatıldı"</string> @@ -884,4 +888,8 @@ <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> diğer uygulama</item> <item quantity="one"><xliff:g id="NUM_APPS_0">%d</xliff:g> diğer uygulama</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensörler kapalı"</string> + <string name="device_services" msgid="1191212554435440592">"Cihaz Hizmetleri"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 6864034ebe7a..a298c6a26589 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Роумінг"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Робочий режим увімкнено."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Заощадження трафіку вимкнено."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Заощадження трафіку ввімкнено."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Конфіденційність датчиків вимкнено."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Конфіденційність датчиків увімкнено."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Яскравість дисплея"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Заряджається"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Передавання даних 2G–3G призупинено"</string> @@ -896,4 +900,7 @@ <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> </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> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 4738bcd9fcb0..3a59029f15e1 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"رومنگ"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"کام موڈ آن ہو گیا۔"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"ڈیٹا سیور آف ہو گیا۔"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"ڈیٹا سرور آن ہو گیا۔"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"سینسر کی رازداری آف ہے۔"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"سینسر کی رازداری آن ہے۔"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"ڈسپلے کی چمک"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"چارج ہو رہا ہے"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ڈیٹا موقوف کر دیا گیا"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 53a29e0de71a..3388bcb63561 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Rouming"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Ishchi rejim yoqildi."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Trafik tejash rejimi o‘chirib qo‘yildi."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Trafik tejash rejimi yoqildi."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Sensor Privacy funksiyasi nofaol."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Sensor Privacy funksiyasi nofaol."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Ekran yorqinligi"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Quvvat olmoqda"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G internet to‘xtatib qo‘yildi"</string> @@ -884,4 +888,8 @@ <item quantity="other">Yana <xliff:g id="NUM_APPS_1">%d</xliff:g> ta ilova</item> <item quantity="one">Yana <xliff:g id="NUM_APPS_0">%d</xliff:g> ta ilova</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensorlar nofaol"</string> + <string name="device_services" msgid="1191212554435440592">"Qurilma xizmatlari"</string> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index ce3da2ac7241..3ebb8dd667cb 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G trở lên"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Chuyển vùng"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Chế độ làm việc đã bật."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Đã tắt Trình tiết kiệm dữ liệu."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Đã bật Trình tiết kiệm dữ liệu."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Đã tắt Bảo mật cảm biến."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Đã bật Bảo mật cảm biến."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Độ sáng màn hình"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Đang sạc"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Đã tạm dừng dữ liệu 2G-3G"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index b9abd4040ea0..d480a8af7384 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"漫游"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"工作模式已开启。"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"流量节省程序已关闭。"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"流量节省程序已开启。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"已关闭传感器隐私设置。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"已开启传感器隐私设置。"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"屏幕亮度"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"正在充电"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G 数据网络已暂停使用"</string> @@ -296,7 +300,7 @@ <skip /> <string name="quick_settings_bluetooth_secondary_label_transient" msgid="4551281899312150640">"正在开启…"</string> <string name="quick_settings_brightness_label" msgid="6968372297018755815">"亮度"</string> - <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"自动旋转"</string> + <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"自动旋转屏幕"</string> <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"自动旋转屏幕"</string> <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g>模式"</string> <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"屏幕方向:锁定"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 5d89c84f0ac1..5c2a5d271071 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"漫遊"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"已開啟工作模式。"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"已關閉數據節省模式。"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"已開啟數據節省模式。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"閂咗感應器私隱功能。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"開咗感應器私隱功能。"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"顯示光暗度"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"正在充電"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"已暫停 2G-3G 數據"</string> @@ -884,4 +888,7 @@ <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> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index bffa9ce5ca88..7ff70d9558d4 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"漫遊"</string> <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"工作模式已開啟。"</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver 已關閉。"</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver 已開啟。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"已關閉感應器隱私設定。"</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"已開啟感應器隱私設定。"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"螢幕亮度"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"充電中"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"已暫停 2G-3G 數據連線"</string> @@ -884,4 +888,8 @@ <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> + <!-- no translation found for music_controls_no_title (5236895307087002011) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index f7369a80c77e..098ed0167c70 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -167,6 +167,8 @@ <string name="data_connection_4g_plus" msgid="1148687201877800700">"4G+"</string> <string name="data_connection_lte" msgid="2694876797724028614">"I-LTE"</string> <string name="data_connection_lte_plus" msgid="3423013208570937424">"I-LTE+"</string> + <string name="data_connection_5g" msgid="6357743323196864504">"5G"</string> + <string name="data_connection_5g_plus" msgid="3284146603743732965">"5G+"</string> <string name="data_connection_cdma" msgid="8176597308239086780">"1X"</string> <string name="data_connection_roaming" msgid="6037232010953697354">"Iyazulazula"</string> <string name="data_connection_edge" msgid="871835227939216682">"I-EDGE"</string> @@ -250,6 +252,8 @@ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Imodi yomsebenzi ivuliwe."</string> <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Iseva yedatha ivaliwe."</string> <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Iseva yedatha ivuliwe."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="5152819588955163090">"Inzwa yobumfihlo ivaliwe."</string> + <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="529705259565826355">"Inzwa yobumfihlo ivuliwe."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Bonisa ukukhanya"</string> <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Iyashaja"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G idatha imisiwe"</string> @@ -884,4 +888,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_1">%d</xliff:g> ezinye izinhlelo zokusebenza</item> <item quantity="other"><xliff:g id="NUM_APPS_1">%d</xliff:g> ezinye izinhlelo zokusebenza</item> </plurals> + <string name="sensor_privacy_mode" msgid="8982771253020769598">"Izinzwa zivaliwe"</string> + <string name="device_services" msgid="1191212554435440592">"Amasevisi edivayisi"</string> + <string name="music_controls_no_title" msgid="5236895307087002011">"Asikho isihloko"</string> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index c94438fa74f1..f384d8f5b357 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2333,4 +2333,7 @@ <!-- Name for device services grouping system uid apps in Ongoing Privacy Dialog [CHAR_LIMIT=NONE] --> <string name="device_services">Device Services</string> + + <!-- What to show on the ambient display player when song doesn't have a title. [CHAR LIMIT=20] --> + <string name="music_controls_no_title">No title</string> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java index 10b5f1c64d85..da143f9bcbe3 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java @@ -258,7 +258,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage Log.v(TAG, "Reloading " + pkg); } } - if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) { + if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction()) + && componentName != null) { @PluginEnabler.DisableReason int disableReason = getPluginEnabler().getDisableReason(componentName); if (disableReason == PluginEnabler.DISABLED_FROM_EXPLICIT_CRASH diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index 6528d8c07a6c..c0ec405e7dc1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -66,17 +66,6 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView { public void onSimStateChanged(int subId, int slotId, State simState) { if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")"); switch(simState) { - // If the SIM is removed, then we must remove the keyguard. It will be put up - // again when the PUK locked SIM is re-entered. - case ABSENT: { - KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId); - // onSimStateChanged callback can fire when the SIM PIN lock is not currently - // active and mCallback is null. - if (mCallback != null) { - mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser()); - } - break; - } case READY: { mRemainingAttempts = -1; resetState(); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 1157f86872ec..b17d117b68e3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -69,14 +69,11 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView { public void onSimStateChanged(int subId, int slotId, State simState) { if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")"); switch(simState) { - // If the SIM is removed, then we must remove the keyguard. It will be put up - // again when the PUK locked SIM is re-entered. - case ABSENT: - // intentional fall-through // If the SIM is unlocked via a key sequence through the emergency dialer, it will // move into the READY state and the PUK lock keyguard should be removed. case READY: { - KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId); + mRemainingAttempts = -1; + mShowDefaultMessage = true; // mCallback can be null if onSimStateChanged callback is called when keyguard // isn't active. if (mCallback != null) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java index 576660431d82..669e6fff525b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java @@ -208,9 +208,11 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe android.app.slice.SliceItem.FORMAT_IMAGE); if (icon != null) { iconDrawable = icon.getIcon().loadDrawable(mContext); - final int width = (int) (iconDrawable.getIntrinsicWidth() - / (float) iconDrawable.getIntrinsicHeight() * mIconSize); - iconDrawable.setBounds(0, 0, Math.max(width, 1), mIconSize); + if (iconDrawable != null) { + final int width = (int) (iconDrawable.getIntrinsicWidth() + / (float) iconDrawable.getIntrinsicHeight() * mIconSize); + iconDrawable.setBounds(0, 0, Math.max(width, 1), mIconSize); + } } button.setCompoundDrawables(iconDrawable, null, null, null); button.setOnClickListener(this); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 416441e33a05..bcd41a076eee 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1936,6 +1936,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { // Even though the subscription is not valid anymore, we need to notify that the // SIM card was removed so we can update the UI. becameAbsent = true; + for (SimData data : mSimDatas.values()) { + // Set the SIM state of all SimData associated with that slot to ABSENT se we + // do not move back into PIN/PUK locked and not detect the change below. + if (data.slotId == slotId) { + data.simState = State.ABSENT; + } + } } else { return; } diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java index 9e7c5ba1d66c..b461f69f10d6 100644 --- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java @@ -19,14 +19,22 @@ import android.content.Intent; import com.android.systemui.plugins.ActivityStarter; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Single common instance of ActivityStarter that can be gotten and referenced from anywhere, but * delegates to an actual implementation such as StatusBar, assuming it exists. */ +@Singleton public class ActivityStarterDelegate implements ActivityStarter { private ActivityStarter mActualStarter; + @Inject + public ActivityStarterDelegate() { + } + @Override public void startPendingIntentDismissingKeyguard(PendingIntent intent) { if (mActualStarter == null) { diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java index 874cdccb8794..6864ea185834 100644 --- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java @@ -48,14 +48,14 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.settingslib.graph.BatteryMeterDrawableBase; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.IconLogger; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 443e389b1d02..6e5042940175 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -38,6 +38,7 @@ import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.power.EnhancedEstimates; @@ -45,7 +46,7 @@ import com.android.systemui.power.PowerUI; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.AmbientPulseManager; -import com.android.systemui.statusbar.DisplayNavigationBarController; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; @@ -54,6 +55,7 @@ import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; +import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationFilter; @@ -78,7 +80,6 @@ import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.ExtensionController; @@ -243,7 +244,7 @@ public class Dependency extends SystemUI { @Inject Lazy<NotificationRemoteInputManager.Callback> mNotificationRemoteInputManagerCallback; @Inject Lazy<InitController> mInitController; @Inject Lazy<AppOpsController> mAppOpsController; - @Inject Lazy<DisplayNavigationBarController> mDisplayNavigationBarController; + @Inject Lazy<NavigationBarController> mNavigationBarController; @Inject Lazy<StatusBarStateController> mStatusBarStateController; @Inject Lazy<NotificationLockscreenUserManager> mNotificationLockscreenUserManager; @Inject Lazy<NotificationGroupAlertTransferHelper> mNotificationGroupAlertTransferHelper; @@ -266,6 +267,8 @@ public class Dependency extends SystemUI { @Inject Lazy<RemoteInputQuickSettingsDisabler> mRemoteInputQuickSettingsDisabler; @Inject Lazy<BubbleController> mBubbleController; @Inject Lazy<NotificationEntryManager> mNotificationEntryManager; + @Inject + Lazy<NotificationAlertingManager> mNotificationAlertingManager; @Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager; @Inject @Named(BG_LOOPER_NAME) Lazy<Looper> mBgLooper; @Inject @Named(BG_HANDLER_NAME) Lazy<Handler> mBgHandler; @@ -407,8 +410,7 @@ public class Dependency extends SystemUI { mProviders.put(AppOpsController.class, mAppOpsController::get); - mProviders.put(DisplayNavigationBarController.class, - mDisplayNavigationBarController::get); + mProviders.put(NavigationBarController.class, mNavigationBarController::get); mProviders.put(StatusBarStateController.class, mStatusBarStateController::get); mProviders.put(NotificationLockscreenUserManager.class, @@ -439,6 +441,7 @@ public class Dependency extends SystemUI { mRemoteInputQuickSettingsDisabler::get); mProviders.put(BubbleController.class, mBubbleController::get); mProviders.put(NotificationEntryManager.class, mNotificationEntryManager::get); + mProviders.put(NotificationAlertingManager.class, mNotificationAlertingManager::get); sDependency = this; } @@ -531,10 +534,18 @@ public class Dependency extends SystemUI { sDependency.destroyDependency(cls, destroy); } + /** + * @deprecated see docs/dagger.md + */ + @Deprecated public static <T> T get(Class<T> cls) { return sDependency.getDependency(cls); } + /** + * @deprecated see docs/dagger.md + */ + @Deprecated public static <T> T get(DependencyKey<T> cls) { return sDependency.getDependency(cls); } diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java new file mode 100644 index 000000000000..1ee1dcf74555 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java @@ -0,0 +1,234 @@ +/* + * 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; + +import com.android.systemui.appops.AppOpsController; +import com.android.systemui.appops.AppOpsControllerImpl; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.VolumeDialogController; +import com.android.systemui.power.PowerNotificationWarnings; +import com.android.systemui.power.PowerUI; +import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.QSTileHost; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl; +import com.android.systemui.statusbar.phone.ManagedProfileController; +import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl; +import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl; +import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback; +import com.android.systemui.statusbar.policy.BatteryController; +import com.android.systemui.statusbar.policy.BatteryControllerImpl; +import com.android.systemui.statusbar.policy.BluetoothController; +import com.android.systemui.statusbar.policy.BluetoothControllerImpl; +import com.android.systemui.statusbar.policy.CastController; +import com.android.systemui.statusbar.policy.CastControllerImpl; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl; +import com.android.systemui.statusbar.policy.ExtensionController; +import com.android.systemui.statusbar.policy.ExtensionControllerImpl; +import com.android.systemui.statusbar.policy.FlashlightController; +import com.android.systemui.statusbar.policy.FlashlightControllerImpl; +import com.android.systemui.statusbar.policy.HotspotController; +import com.android.systemui.statusbar.policy.HotspotControllerImpl; +import com.android.systemui.statusbar.policy.IconLogger; +import com.android.systemui.statusbar.policy.IconLoggerImpl; +import com.android.systemui.statusbar.policy.KeyguardMonitor; +import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; +import com.android.systemui.statusbar.policy.LocationController; +import com.android.systemui.statusbar.policy.LocationControllerImpl; +import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.NetworkControllerImpl; +import com.android.systemui.statusbar.policy.NextAlarmController; +import com.android.systemui.statusbar.policy.NextAlarmControllerImpl; +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.UserInfoController; +import com.android.systemui.statusbar.policy.UserInfoControllerImpl; +import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.statusbar.policy.ZenModeControllerImpl; +import com.android.systemui.tuner.TunerService; +import com.android.systemui.tuner.TunerServiceImpl; +import com.android.systemui.volume.VolumeDialogControllerImpl; + +import dagger.Binds; +import dagger.Module; + +/** + * Maps interfaces to implementations for use with Dagger. + */ +@Module +public abstract class DependencyBinder { + + /** + */ + @Binds + public abstract ActivityStarter provideActivityStarter(ActivityStarterDelegate delegate); + + /** + */ + @Binds + public abstract BluetoothController provideBluetoothController( + BluetoothControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract LocationController provideLocationController( + LocationControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract RotationLockController provideRotationLockController( + RotationLockControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract NetworkController provideNetworkController( + NetworkControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract ZenModeController provideZenModeController( + ZenModeControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract HotspotController provideHotspotController( + HotspotControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract AppOpsController provideAppOpsController( + AppOpsControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract NotificationRemoteInputManager.Callback provideNotificationRemoteInputManager( + StatusBarRemoteInputCallback callbackImpl); + + /** + */ + @Binds + public abstract IconLogger provideIconLogger(IconLoggerImpl loggerImpl); + + /** + */ + @Binds + public abstract CastController provideCastController(CastControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract FlashlightController provideFlashlightController( + FlashlightControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract KeyguardMonitor provideKeyguardMonitor(KeyguardMonitorImpl controllerImpl); + + /** + */ + @Binds + public abstract UserInfoController provideUserInfoContrller( + UserInfoControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract BatteryController provideBatteryController( + BatteryControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract ManagedProfileController provideManagedProfileController( + ManagedProfileControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract NextAlarmController provideNextAlarmController( + NextAlarmControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract DeviceProvisionedController provideDeviceProvisionedController( + DeviceProvisionedControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract SecurityController provideSecurityController( + SecurityControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract TunerService provideTunerService(TunerServiceImpl controllerImpl); + + /** + */ + @Binds + public abstract DarkIconDispatcher provideDarkIconDispatcher( + DarkIconDispatcherImpl controllerImpl); + + /** + */ + @Binds + public abstract StatusBarIconController provideStatusBarIconController( + StatusBarIconControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract ExtensionController provideExtensionController( + ExtensionControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract VolumeDialogController provideVolumeDialogController( + VolumeDialogControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract ForegroundServiceController provideForegroundService( + ForegroundServiceControllerImpl controllerImpl); + + /** + */ + @Binds + public abstract PowerUI.WarningsUI provideWarningsUi(PowerNotificationWarnings 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 3ca7b971a468..5c9b9990058e 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java @@ -18,13 +18,11 @@ package com.android.systemui; import static com.android.systemui.Dependency.BG_HANDLER_NAME; import static com.android.systemui.Dependency.BG_LOOPER_NAME; -import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME; import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; import android.annotation.Nullable; import android.content.Context; -import android.hardware.SensorManager; import android.hardware.SensorPrivacyManager; import android.os.Handler; import android.os.HandlerThread; @@ -40,82 +38,17 @@ import com.android.internal.app.ColorDisplayController; import com.android.internal.logging.MetricsLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.systemui.appops.AppOpsController; -import com.android.systemui.appops.AppOpsControllerImpl; -import com.android.systemui.colorextraction.SysuiColorExtractor; -import com.android.systemui.keyguard.ScreenLifecycle; -import com.android.systemui.keyguard.WakefulnessLifecycle; -import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.PluginInitializerImpl; -import com.android.systemui.plugins.VolumeDialogController; -import com.android.systemui.power.PowerNotificationWarnings; -import com.android.systemui.power.PowerUI; -import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; -import com.android.systemui.statusbar.DisplayNavigationBarController; -import com.android.systemui.statusbar.NotificationRemoteInputManager; -import com.android.systemui.statusbar.VibratorHelper; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; -import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl; -import com.android.systemui.statusbar.phone.LightBarController; -import com.android.systemui.statusbar.phone.LockscreenGestureLogger; -import com.android.systemui.statusbar.phone.ManagedProfileController; -import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; -import com.android.systemui.statusbar.phone.StatusBarIconController; -import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl; -import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback; -import com.android.systemui.statusbar.phone.StatusBarWindowController; -import com.android.systemui.statusbar.policy.AccessibilityController; -import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; -import com.android.systemui.statusbar.policy.BatteryController; -import com.android.systemui.statusbar.policy.BatteryControllerImpl; -import com.android.systemui.statusbar.policy.BluetoothController; -import com.android.systemui.statusbar.policy.BluetoothControllerImpl; -import com.android.systemui.statusbar.policy.CastController; -import com.android.systemui.statusbar.policy.CastControllerImpl; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DataSaverController; -import com.android.systemui.statusbar.policy.DeviceProvisionedController; -import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl; -import com.android.systemui.statusbar.policy.ExtensionController; -import com.android.systemui.statusbar.policy.ExtensionControllerImpl; -import com.android.systemui.statusbar.policy.FlashlightController; -import com.android.systemui.statusbar.policy.FlashlightControllerImpl; -import com.android.systemui.statusbar.policy.HotspotController; -import com.android.systemui.statusbar.policy.HotspotControllerImpl; -import com.android.systemui.statusbar.policy.IconLogger; -import com.android.systemui.statusbar.policy.IconLoggerImpl; -import com.android.systemui.statusbar.policy.KeyguardMonitor; -import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; -import com.android.systemui.statusbar.policy.LocationController; -import com.android.systemui.statusbar.policy.LocationControllerImpl; import com.android.systemui.statusbar.policy.NetworkController; -import com.android.systemui.statusbar.policy.NetworkControllerImpl; -import com.android.systemui.statusbar.policy.NextAlarmController; -import com.android.systemui.statusbar.policy.NextAlarmControllerImpl; -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.UserInfoController; -import com.android.systemui.statusbar.policy.UserInfoControllerImpl; -import com.android.systemui.statusbar.policy.UserSwitcherController; -import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.statusbar.policy.ZenModeControllerImpl; -import com.android.systemui.tuner.TunablePadding; -import com.android.systemui.tuner.TunablePadding.TunablePaddingService; -import com.android.systemui.tuner.TunerService; -import com.android.systemui.tuner.TunerServiceImpl; -import com.android.systemui.util.AsyncSensorManager; -import com.android.systemui.util.leak.GarbageMonitor; import com.android.systemui.util.leak.LeakDetector; -import com.android.systemui.util.leak.LeakReporter; -import com.android.systemui.volume.VolumeDialogControllerImpl; import javax.inject.Named; import javax.inject.Singleton; @@ -165,256 +98,12 @@ public class DependencyProvider { @Singleton @Provides - public ActivityStarter provideActivityStarter() { - return new ActivityStarterDelegate(); - } - - @Singleton - @Provides - public InitController provideInitController() { - return new InitController(); - } - - @Singleton - @Provides - public ActivityStarterDelegate provideActivityStarterDelegate(ActivityStarter starter) { - return (ActivityStarterDelegate) starter; - } - - @Singleton - @Provides - public AsyncSensorManager provideAsyncSensorManager(Context context, PluginManager manager) { - return new AsyncSensorManager(context.getSystemService(SensorManager.class), - manager); - - } - - @Singleton - @Provides - public BluetoothController provideBluetoothController(Context context, - @Named(BG_LOOPER_NAME) Looper looper) { - return new BluetoothControllerImpl(context, looper); - - } - - @Singleton - @Provides - public LocationController provideLocationController(Context context, - @Named(BG_LOOPER_NAME) Looper bgLooper) { - return new LocationControllerImpl(context, bgLooper); - - } - - @Singleton - @Provides - public RotationLockController provideRotationLockController(Context context) { - return new RotationLockControllerImpl(context); - - } - - @Singleton - @Provides - public NetworkController provideNetworkController(Context context, - @Named(BG_LOOPER_NAME) Looper bgLooper, DeviceProvisionedController controller) { - return new NetworkControllerImpl(context, bgLooper, - controller); - - } - - @Singleton - @Provides - public ZenModeController provideZenModeController(Context context, - @Named(MAIN_HANDLER_NAME) Handler mainHandler) { - return new ZenModeControllerImpl(context, mainHandler); - - } - - @Singleton - @Provides - public HotspotController provideHotspotController(Context context) { - return new HotspotControllerImpl(context); - - } - - @Singleton - @Provides - public CastController provideCastController(Context context) { - return new CastControllerImpl(context); - - } - - @Singleton - @Provides - public FlashlightController provideFlashlightController(Context context) { - return new FlashlightControllerImpl(context); - - } - - @Singleton - @Provides - public KeyguardMonitor provideKeyguardMonitor(Context context) { - return new KeyguardMonitorImpl(context); - - } - - @Singleton - @Provides - public UserSwitcherController provideUserSwitcherController(Context context, - KeyguardMonitor keyguardMonitor, @Named(MAIN_HANDLER_NAME) Handler mainHandler, - ActivityStarter activityStarter) { - return new UserSwitcherController(context, keyguardMonitor, mainHandler, activityStarter); - } - - @Singleton - @Provides - public UserInfoController provideUserInfoContrller(Context context) { - return new UserInfoControllerImpl(context); - - } - - @Singleton - @Provides - public BatteryController provideBatteryController(Context context) { - return new BatteryControllerImpl(context); - - } - - @Singleton - @Provides - public ColorDisplayController provideColorDisplayController(Context context) { - return new ColorDisplayController(context); - - } - - @Singleton - @Provides - public ManagedProfileController provideManagedProfileController(Context context) { - return new ManagedProfileControllerImpl(context); - - } - - @Singleton - @Provides - public NextAlarmController provideNextAlarmController(Context context) { - return new NextAlarmControllerImpl(context); - - } - - @Singleton - @Provides public DataSaverController provideDataSaverController(NetworkController networkController) { return networkController.getDataSaverController(); } @Singleton @Provides - public AccessibilityController provideAccessibilityController(Context context) { - return new AccessibilityController(context); - - } - - @Singleton - @Provides - public DeviceProvisionedController provideDeviceProvisionedController(Context context) { - return new DeviceProvisionedControllerImpl(context); - - } - - @Singleton - @Provides - public PluginManager providePluginManager(Context context) { - return new PluginManagerImpl(context, new PluginInitializerImpl()); - - } - - @Singleton - @Provides - public SecurityController provideSecurityController(Context context) { - return new SecurityControllerImpl(context); - - } - - @Singleton - @Provides - public LeakDetector provideLeakDetector() { - return LeakDetector.create(); - - } - - @Singleton - @Provides - public LeakReporter provideLeakReporter(Context context, LeakDetector detector, - @Nullable @Named(LEAK_REPORT_EMAIL_NAME) String email) { - return new LeakReporter(context, detector, email); - } - - @Singleton - @Provides - public GarbageMonitor provideGarbageMonitor(Context context, - @Named(BG_LOOPER_NAME) Looper bgLooper, LeakDetector detector, LeakReporter reporter) { - return new GarbageMonitor(context, bgLooper, detector, reporter); - } - - @Singleton - @Provides - public TunerService provideTunerService(Context context) { - return new TunerServiceImpl(context); - - } - - @Singleton - @Provides - public StatusBarWindowController provideStatusBarWindowController(Context context) { - return new StatusBarWindowController(context); - - } - - @Singleton - @Provides - public DarkIconDispatcher provideDarkIconDispatcher(Context context) { - return new DarkIconDispatcherImpl(context); - } - - @Singleton - @Provides - public ConfigurationController provideConfigurationController(Context context) { - return new ConfigurationControllerImpl(context); - - } - - @Singleton - @Provides - public StatusBarIconController provideStatusBarIconController(Context context) { - return new StatusBarIconControllerImpl(context); - - } - - @Singleton - @Provides - public ScreenLifecycle provideScreenLifecycle() { - return new ScreenLifecycle(); - } - - @Singleton - @Provides - public WakefulnessLifecycle provideWakefulnessLifecycle() { - return new WakefulnessLifecycle(); - } - - @Singleton - @Provides - public ExtensionController provideExtensionController(Context context) { - return new ExtensionControllerImpl(context); - } - - @Singleton - @Provides - public PluginDependencyProvider providePluginDependency(PluginManager pluginManager) { - return new PluginDependencyProvider(pluginManager); - } - - @Singleton - @Provides @Nullable public LocalBluetoothManager provideLocalBluetoothController(Context context, @Named(BG_HANDLER_NAME) Handler bgHandler) { @@ -424,72 +113,8 @@ public class DependencyProvider { @Singleton @Provides - public VolumeDialogController provideVolumeDialogController(Context context) { - return new VolumeDialogControllerImpl(context); - - } - - @Singleton - @Provides public MetricsLogger provideMetricsLogger() { return new MetricsLogger(); - - } - - @Singleton - @Provides - public AccessibilityManagerWrapper provideAccessibilityManagerWrapper(Context context) { - return new AccessibilityManagerWrapper(context); - - } - - @Singleton - @Provides - // Creating a new instance will trigger color extraction. - // Thankfully this only happens once - during boot - and WallpaperManagerService - // loads colors from cache. - public SysuiColorExtractor provideSysuiColorExtractor(Context context) { - return new SysuiColorExtractor(context); - - } - - @Singleton - @Provides - public TunablePadding.TunablePaddingService provideTunablePaddingService() { - return new TunablePaddingService(); - - } - - @Singleton - @Provides - public ForegroundServiceController provideForegroundService(Context context) { - return new ForegroundServiceControllerImpl(context); - - } - - @Singleton - @Provides - public UiOffloadThread provideUiOffloadThread() { - return new UiOffloadThread(); - } - - @Singleton - @Provides - public PowerUI.WarningsUI provideWarningsUi(Context context) { - return new PowerNotificationWarnings(context); - } - - @Singleton - @Provides - public IconLogger provideIconLogger(Context context, @Named(BG_LOOPER_NAME) Looper bgLooper, - MetricsLogger logger) { - return new IconLoggerImpl(context, bgLooper, logger); - } - - @Singleton - @Provides - public LightBarController provideLightBarController(Context context) { - return new LightBarController(context); } @Singleton @@ -500,19 +125,6 @@ public class DependencyProvider { @Singleton @Provides - public OverviewProxyService provideOverviewProxyService(Context context) { - return new OverviewProxyService(context); - } - - @Singleton - @Provides - public VibratorHelper provideVibratorHelper(Context context) { - return new VibratorHelper(context); - - } - - @Singleton - @Provides public IStatusBarService provideIStatusBarService() { return IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); @@ -521,50 +133,52 @@ public class DependencyProvider { @Singleton @Provides // Single instance of DisplayMetrics, gets updated by StatusBar, but can be used -// anywhere it is needed. + // anywhere it is needed. public DisplayMetrics provideDisplayMetrics() { return new DisplayMetrics(); - } @Singleton @Provides - public LockscreenGestureLogger provideLockscreenGestureLogger() { - return new LockscreenGestureLogger(); + public ShadeController provideShadeController(Context context) { + return SysUiServiceProvider.getComponent(context, StatusBar.class); } @Singleton @Provides - public ShadeController provideShadeController(Context context) { - return SysUiServiceProvider.getComponent(context, StatusBar.class); + public SensorPrivacyManager provideSensorPrivacyManager(Context context) { + return context.getSystemService(SensorPrivacyManager.class); } @Singleton @Provides - public NotificationRemoteInputManager.Callback provideNotificationRemoteInputManager( - Context context) { - return new StatusBarRemoteInputCallback(context); + public LeakDetector provideLeakDetector() { + return LeakDetector.create(); } @Singleton @Provides - public AppOpsController provideAppOpsController(Context context, - @Named(BG_LOOPER_NAME) Looper bgLooper) { - return new AppOpsControllerImpl(context, bgLooper); + public ColorDisplayController provideColorDisplayController(Context context) { + return new ColorDisplayController(context); + } + @Singleton + @Provides + public PluginManager providePluginManager(Context context) { + return new PluginManagerImpl(context, new PluginInitializerImpl()); } @Singleton @Provides - public DisplayNavigationBarController provideDisplayNavigationBarController(Context context, + public NavigationBarController provideNavigationBarController(Context context, @Named(MAIN_HANDLER_NAME) Handler mainHandler) { - return new DisplayNavigationBarController(context, mainHandler); + return new NavigationBarController(context, mainHandler); } @Singleton @Provides - public SensorPrivacyManager provideSensorPrivacyManager(Context context) { - return context.getSystemService(SensorPrivacyManager.class); + public ConfigurationController provideConfigurationController(Context context) { + return new ConfigurationControllerImpl(context); } } diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java index bab472c2e687..ae446ddc91ab 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java @@ -29,9 +29,13 @@ import com.android.internal.messages.nano.SystemMessageProto; import java.util.Arrays; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Foreground service controller, a/k/a Dianne's Dungeon. */ +@Singleton public class ForegroundServiceControllerImpl implements ForegroundServiceController { @@ -45,6 +49,7 @@ public class ForegroundServiceControllerImpl private final SparseArray<UserServices> mUserServices = new SparseArray<>(); private final Object mMutex = new Object(); + @Inject public ForegroundServiceControllerImpl(Context context) { mContext = context; } diff --git a/packages/SystemUI/src/com/android/systemui/InitController.java b/packages/SystemUI/src/com/android/systemui/InitController.java index 81d32517b27a..a2dd12389fa9 100644 --- a/packages/SystemUI/src/com/android/systemui/InitController.java +++ b/packages/SystemUI/src/com/android/systemui/InitController.java @@ -16,10 +16,14 @@ package com.android.systemui; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Created by {@link Dependency} on SystemUI startup. Add tasks which need to be executed only * after all other dependencies have been created. */ +@Singleton public class InitController { /** @@ -29,6 +33,10 @@ public class InitController { private final ArrayList<Runnable> mTasks = new ArrayList<>(); + @Inject + public InitController() { + } + /** * Add a task to be executed after {@link Dependency#start()} * @param runnable the task to be executed diff --git a/packages/SystemUI/src/com/android/systemui/SystemBars.java b/packages/SystemUI/src/com/android/systemui/SystemBars.java index 6edc23be8e23..4285af08e734 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemBars.java +++ b/packages/SystemUI/src/com/android/systemui/SystemBars.java @@ -16,6 +16,8 @@ package com.android.systemui; import android.util.Log; +import com.android.systemui.statusbar.phone.StatusBar; + import java.io.FileDescriptor; import java.io.PrintWriter; @@ -63,6 +65,11 @@ public class SystemBars extends SystemUI { } mStatusBar.mContext = mContext; mStatusBar.mComponents = mComponents; + if (mStatusBar instanceof StatusBar) { + SystemUIFactory.getInstance().getRootComponent() + .getStatusBarInjector() + .createStatusBar((StatusBar) mStatusBar); + } mStatusBar.start(); if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName()); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 384a14c70e9c..e3bfdc911941 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -34,7 +34,6 @@ import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.EnhancedEstimatesImpl; -import com.android.systemui.qs.QSTileHost; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -52,10 +51,10 @@ import com.android.systemui.statusbar.phone.NotificationIconAreaController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ScrimState; import com.android.systemui.statusbar.phone.StatusBar; -import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.util.InjectionInflationController; +import com.android.systemui.util.leak.GarbageMonitor; import com.android.systemui.volume.VolumeDialogComponent; import java.util.function.Consumer; @@ -144,11 +143,6 @@ public class SystemUIFactory { return new KeyguardIndicationController(context, indicationArea, lockIcon); } - public QSTileHost createQSTileHost(Context context, StatusBar statusBar, - StatusBarIconController iconController) { - return new QSTileHost(context, statusBar, iconController); - } - public VolumeDialogComponent createVolumeDialogComponent(SystemUI systemUi, Context context) { return new VolumeDialogComponent(systemUi, context); } @@ -221,11 +215,15 @@ public class SystemUIFactory { } @Singleton - @Component(modules = {SystemUIFactory.class, DependencyProvider.class, ContextHolder.class}) + @Component(modules = {SystemUIFactory.class, DependencyProvider.class, DependencyBinder.class, + ContextHolder.class}) public interface SystemUIRootComponent { @Singleton Dependency.DependencyInjector createDependency(); + @Singleton + StatusBar.StatusBarInjector getStatusBarInjector(); + /** * FragmentCreator generates all Fragments that need injection. */ @@ -236,5 +234,8 @@ public class SystemUIFactory { * ViewCreator generates all Views that need injection. */ InjectionInflationController.ViewCreator createViewCreator(); + + @Singleton + GarbageMonitor createGarbageMonitor(); } } diff --git a/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java b/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java index 82fd9b304195..a726b42f714f 100644 --- a/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java +++ b/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java @@ -20,14 +20,22 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Thread that offloads work from the UI thread but that is still perceptible to the user, so the * priority is the same as the main thread. */ +@Singleton public class UiOffloadThread { private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor(); + @Inject + public UiOffloadThread() { + } + public Future<?> submit(Runnable runnable) { return mExecutorService.submit(runnable); } diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index af6ee1f4179a..e3bcb37474db 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -16,6 +16,8 @@ package com.android.systemui.appops; +import static com.android.systemui.Dependency.BG_LOOPER_NAME; + import android.app.AppOpsManager; import android.content.Context; import android.os.Handler; @@ -32,12 +34,17 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + /** * Controller to keep track of applications that have requested access to given App Ops * * It can be subscribed to with callbacks. Additionally, it passes on the information to * NotificationPresenter to be displayed to the user. */ +@Singleton public class AppOpsControllerImpl implements AppOpsController, AppOpsManager.OnOpActiveChangedListener, AppOpsManager.OnOpNotedListener { @@ -65,7 +72,8 @@ public class AppOpsControllerImpl implements AppOpsController, AppOpsManager.OP_FINE_LOCATION }; - public AppOpsControllerImpl(Context context, Looper bgLooper) { + @Inject + public AppOpsControllerImpl(Context context, @Named(BG_LOOPER_NAME) Looper bgLooper) { mContext = context; mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mBGHandler = new H(bgLooper); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index c8595ebb5fca..881aa18285ff 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -33,7 +33,6 @@ import android.view.WindowManager; import android.widget.FrameLayout; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.phone.StatusBarWindowController; @@ -122,12 +121,12 @@ public class BubbleController { } @Inject - public BubbleController(Context context) { + public BubbleController(Context context, StatusBarWindowController statusBarWindowController) { mContext = context; WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mDisplaySize = new Point(); wm.getDefaultDisplay().getSize(mDisplaySize); - mStatusBarWindowController = Dependency.get(StatusBarWindowController.class); + mStatusBarWindowController = statusBarWindowController; } /** diff --git a/packages/SystemUI/src/com/android/systemui/car/CarNotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/car/CarNotificationMediaManager.java deleted file mode 100644 index f34d6b3e03e7..000000000000 --- a/packages/SystemUI/src/com/android/systemui/car/CarNotificationMediaManager.java +++ /dev/null @@ -1,30 +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.car; - -import android.content.Context; - -import com.android.systemui.statusbar.NotificationMediaManager; - -public class CarNotificationMediaManager extends NotificationMediaManager { - public CarNotificationMediaManager(Context context) { - super(context); - } - - @Override - public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) { - // Do nothing, we don't want to display media art in the lock screen for a car. - } -} diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java index 3c8a461d3f73..fdf18ce24f50 100644 --- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java @@ -39,9 +39,13 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Arrays; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * ColorExtractor aware of wallpaper visibility */ +@Singleton public class SysuiColorExtractor extends ColorExtractor implements Dumpable { private static final String TAG = "SysuiColorExtractor"; private boolean mWallpaperVisible; @@ -49,6 +53,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { // Colors to return when the wallpaper isn't visible private final GradientColors mWpHiddenColors; + @Inject public SysuiColorExtractor(Context context) { this(context, new Tonal(context), true); } diff --git a/packages/SystemUI/src/com/android/systemui/dock/DockManager.java b/packages/SystemUI/src/com/android/systemui/dock/DockManager.java new file mode 100644 index 000000000000..fa5a114c7187 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dock/DockManager.java @@ -0,0 +1,58 @@ +/* + * 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.dock; + +/** + * Allows an app to handle dock events + */ +public interface DockManager { + + /** + * Uninitialized / undocking dock states + */ + int STATE_NONE = 0; + /** + * The state for docking + */ + int STATE_DOCKED = 1; + /** + * The state for docking without showing UI + */ + int STATE_DOCKED_HIDE = 2; + + /** + * Add a dock event listener into manager + * + * @param callback A {@link DockEventListener} which want to add + */ + void addListener(DockEventListener callback); + + /** + * Remove the added listener from dock manager + * + * @param callback A {@link DockEventListener} which want to remove + */ + void removeListener(DockEventListener callback); + + /** Callback for receiving dock events */ + interface DockEventListener { + /** + * Override to handle dock events + */ + void onEvent(int event); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java new file mode 100644 index 000000000000..9fc22340ea22 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java @@ -0,0 +1,156 @@ +/* + * 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.doze; + +import android.content.Context; +import android.os.Handler; +import android.os.UserHandle; +import android.util.Log; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.dock.DockManager; +import com.android.systemui.doze.DozeMachine.State; + +import java.io.PrintWriter; + +/** + * Handles dock events for ambient state changes. + */ +public class DozeDockHandler implements DozeMachine.Part { + + private static final String TAG = "DozeDockHandler"; + private static final boolean DEBUG = DozeService.DEBUG; + + private final DozeMachine mMachine; + private final DozeHost mDozeHost; + private final AmbientDisplayConfiguration mConfig; + private final Handler mHandler; + private final DockEventListener mDockEventListener = new DockEventListener(); + private final DockManager mDockManager; + + private int mDockState = DockManager.STATE_NONE; + + public DozeDockHandler(Context context, DozeMachine machine, DozeHost dozeHost, + AmbientDisplayConfiguration config, Handler handler) { + mMachine = machine; + mDozeHost = dozeHost; + mConfig = config; + mHandler = handler; + mDockManager = SysUiServiceProvider.getComponent(context, DockManager.class); + } + + @Override + public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { + switch (newState) { + case INITIALIZED: + mDockEventListener.register(); + break; + case DOZE_AOD: + if (mDockState == DockManager.STATE_DOCKED_HIDE) { + mMachine.requestState(State.DOZE); + break; + } + // continue below + case DOZE: + if (mDockState == DockManager.STATE_DOCKED) { + mHandler.post(() -> requestPulse(newState)); + } + break; + case FINISH: + mDockEventListener.unregister(); + break; + default: + // no-op + } + } + + private void requestPulse(State dozeState) { + if (mDozeHost.isPulsingBlocked() || !dozeState.canPulse()) { + return; + } + + mMachine.requestPulse(DozeLog.PULSE_REASON_DOCKING); + } + + private void requestPulseOutNow(State dozeState) { + if (dozeState == State.DOZE_REQUEST_PULSE || dozeState == State.DOZE_PULSING) { + final int pulseReason = mMachine.getPulseReason(); + if (pulseReason == DozeLog.PULSE_REASON_DOCKING) { + mDozeHost.stopPulsing(); + } + } + } + + private boolean isDocked() { + return mDockState == DockManager.STATE_DOCKED + || mDockState == DockManager.STATE_DOCKED_HIDE; + } + + @Override + public void dump(PrintWriter pw) { + pw.print(" DozeDockTriggers docking="); pw.println(isDocked()); + } + + private class DockEventListener implements DockManager.DockEventListener { + private boolean mRegistered; + + @Override + public void onEvent(int event) { + if (DEBUG) Log.d(TAG, "dock event = " + event); + final DozeMachine.State dozeState = mMachine.getState(); + mDockState = event; + switch (mDockState) { + case DockManager.STATE_DOCKED: + requestPulse(dozeState); + break; + case DockManager.STATE_NONE: + if (dozeState == State.DOZE + && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) { + mMachine.requestState(State.DOZE_AOD); + break; + } + // continue below + case DockManager.STATE_DOCKED_HIDE: + requestPulseOutNow(dozeState); + break; + default: + // no-op + } + } + + void register() { + if (mRegistered) { + return; + } + if (mDockManager != null) { + mDockManager.addListener(this); + } + mRegistered = true; + } + + void unregister() { + if (!mRegistered) { + return; + } + if (mDockManager != null) { + mDockManager.removeListener(this); + } + mRegistered = false; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index d93ed1785a0a..58ae555dbff1 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -68,7 +68,8 @@ public class DozeFactory { new DozeScreenState(wrappedService, handler, params, wakeLock), createDozeScreenBrightness(context, wrappedService, sensorManager, host, params, handler), - new DozeWallpaperState(context) + new DozeWallpaperState(context), + new DozeDockHandler(context, machine, host, config, handler) }); return machine; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index 1e61a77a76cf..4cb1feebcce4 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -17,7 +17,6 @@ package com.android.systemui.doze; import android.annotation.NonNull; -import android.app.PendingIntent; /** * Interface the doze service uses to communicate with the rest of system UI. @@ -34,7 +33,6 @@ public interface DozeHost { boolean isProvisioned(); boolean isBlockingDoze(); - void startPendingIntentDismissingKeyguard(PendingIntent intent); void extendPulse(); void setAnimateWakeup(boolean animateWakeup); @@ -48,10 +46,9 @@ public interface DozeHost { void onIgnoreTouchWhilePulsing(boolean ignore); /** - * If the device was waken up by a passive interrupt that will show the lock screen without - * expanding the notification panel/shade. + * Leaves pulsing state, going back to ambient UI. */ - void setPassiveInterrupt(boolean lightInterrupt); + void stopPulsing(); interface Callback { /** diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java index 974cd8804841..50003e3a6a38 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java @@ -35,7 +35,7 @@ public class DozeLog { private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50; static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); - private static final int REASONS = 7; + private static final int REASONS = 9; public static final int PULSE_REASON_NONE = -1; public static final int PULSE_REASON_INTENT = 0; @@ -44,7 +44,9 @@ public class DozeLog { public static final int PULSE_REASON_SENSOR_PICKUP = 3; public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4; public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5; - public static final int REASON_SENSOR_WAKE_UP = 6; + public static final int PULSE_REASON_DOCKING = 6; + public static final int REASON_SENSOR_WAKE_UP = 7; + public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8; private static boolean sRegisterKeyguardCallback = true; @@ -177,15 +179,6 @@ public class DozeLog { } /** - * Appends lock screen wake up event to the logs. - * @param wake if we're waking up or sleeping. - */ - public static void traceLockScreenWakeUp(boolean wake) { - if (!ENABLED) return; - log("wakeLockScreen " + wake); - } - - /** * Appends wake-display event to the logs. * @param wake if we're waking up or sleeping. */ @@ -211,6 +204,8 @@ public class DozeLog { case PULSE_REASON_SENSOR_PICKUP: return "pickup"; case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap"; case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress"; + case PULSE_REASON_DOCKING: return "docking"; + case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen"; case REASON_SENSOR_WAKE_UP: return "wakeup"; default: throw new IllegalArgumentException("bad reason: " + pulseReason); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index c2676d099481..04362c17141c 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -17,6 +17,7 @@ package com.android.systemui.doze; import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_DISPLAY; +import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN; import android.annotation.AnyThread; import android.app.ActivityManager; @@ -115,10 +116,17 @@ public class DozeSensors { new PluginSensor( new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY), Settings.Secure.DOZE_WAKE_SCREEN_GESTURE, - true /* configured */, + mConfig.wakeScreenGestureAvailable(), DozeLog.REASON_SENSOR_WAKE_UP, false /* reports touch coordinates */, false /* touchscreen */), + new PluginSensor( + new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN), + Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, + mConfig.wakeScreenGestureAvailable(), + DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, + false /* reports touch coordinates */, + false /* touchscreen */), }; mProxSensor = new ProxSensor(policy); @@ -351,7 +359,9 @@ public class DozeSensors { } protected boolean enabledBySetting() { - if (TextUtils.isEmpty(mSetting)) { + if (!mConfig.enabled(UserHandle.USER_CURRENT)) { + return false; + } else if (TextUtils.isEmpty(mSetting)) { return true; } return Settings.Secure.getIntForUser(mResolver, mSetting, mSettingDefault ? 1 : 0, diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 1da8976b1b77..6a9b6899d509 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -135,11 +135,12 @@ public class DozeTriggers implements DozeMachine.Part { boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP; boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS; boolean isWakeDisplay = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP; + boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN; boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0; if (isWakeDisplay) { onWakeScreen(wakeEvent); - } else if (isLongPress) { + } else if (isLongPress || isWakeLockScreen) { requestPulse(pulseReason, sensorPerformedProxCheck); } else { proximityCheckThenCall((result) -> { @@ -151,13 +152,11 @@ public class DozeTriggers implements DozeMachine.Part { mDozeHost.onDoubleTap(screenX, screenY); mMachine.wakeUp(); } else if (isPickup) { - mDozeHost.setPassiveInterrupt(true); mMachine.wakeUp(); } else { mDozeHost.extendPulse(); } }, sensorPerformedProxCheck, pulseReason); - return; } if (isPickup) { @@ -221,7 +220,6 @@ public class DozeTriggers implements DozeMachine.Part { case INITIALIZED: mBroadcastReceiver.register(mContext); mDozeHost.addCallback(mHostCallback); - mDozeHost.setPassiveInterrupt(false); checkTriggersAtInit(); break; case DOZE: @@ -231,7 +229,6 @@ public class DozeTriggers implements DozeMachine.Part { mDozeSensors.reregisterAllSensors(); } mDozeSensors.setListening(true); - mDozeHost.setPassiveInterrupt(false); if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) { onWakeScreen(false); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/LockScreenWakeUpController.java b/packages/SystemUI/src/com/android/systemui/doze/LockScreenWakeUpController.java deleted file mode 100644 index ebfafce7a2ba..000000000000 --- a/packages/SystemUI/src/com/android/systemui/doze/LockScreenWakeUpController.java +++ /dev/null @@ -1,121 +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.doze; - -import android.content.Context; -import android.os.Handler; -import android.os.PowerManager; -import android.os.SystemClock; -import android.os.UserHandle; -import android.util.Log; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.hardware.AmbientDisplayConfiguration; -import com.android.systemui.Dependency; -import com.android.systemui.plugins.SensorManagerPlugin; -import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.util.AsyncSensorManager; - -/** - * Controller responsible for waking up or making the device sleep based on ambient sensors. - */ -public class LockScreenWakeUpController implements StatusBarStateController.StateListener, - SensorManagerPlugin.SensorEventListener { - - private static final String TAG = LockScreenWakeUpController.class.getSimpleName(); - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - private final AsyncSensorManager mAsyncSensorManager; - private final SensorManagerPlugin.Sensor mSensor; - private final AmbientDisplayConfiguration mAmbientConfiguration; - private final PowerManager mPowerManager; - private final DozeHost mDozeHost; - private final Handler mHandler; - private boolean mRegistered; - private boolean mDozing; - - public LockScreenWakeUpController(Context context, DozeHost dozeHost) { - this(Dependency.get(AsyncSensorManager.class), - new SensorManagerPlugin.Sensor(SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN), - new AmbientDisplayConfiguration(context), - context.getSystemService(PowerManager.class), - dozeHost, Dependency.get(StatusBarStateController.class), new Handler()); - } - - @VisibleForTesting - public LockScreenWakeUpController(AsyncSensorManager asyncSensorManager, - SensorManagerPlugin.Sensor sensor, AmbientDisplayConfiguration ambientConfiguration, - PowerManager powerManager, DozeHost dozeHost, - StatusBarStateController statusBarStateController, Handler handler) { - mAsyncSensorManager = asyncSensorManager; - mSensor = sensor; - mAmbientConfiguration = ambientConfiguration; - mPowerManager = powerManager; - mDozeHost = dozeHost; - mHandler = handler; - statusBarStateController.addCallback(this); - } - - @Override - public void onStateChanged(int newState) { - boolean isLockScreen = newState == StatusBarState.KEYGUARD - || newState == StatusBarState.SHADE_LOCKED; - - if (!mAmbientConfiguration.wakeLockScreenGestureEnabled(UserHandle.USER_CURRENT)) { - if (mRegistered) { - mAsyncSensorManager.unregisterPluginListener(mSensor, this); - mRegistered = false; - } - return; - } - - if (isLockScreen && !mRegistered) { - mAsyncSensorManager.registerPluginListener(mSensor, this); - mRegistered = true; - } else if (!isLockScreen && mRegistered) { - mAsyncSensorManager.unregisterPluginListener(mSensor, this); - mRegistered = false; - } - } - - @Override - public void onDozingChanged(boolean isDozing) { - mDozing = isDozing; - } - - @Override - public void onSensorChanged(SensorManagerPlugin.SensorEvent event) { - mHandler.post(()-> { - float[] rawValues = event.getValues(); - boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0; - - DozeLog.traceLockScreenWakeUp(wakeEvent); - if (wakeEvent && mDozing) { - mDozeHost.setPassiveInterrupt(true); - if (DEBUG) Log.d(TAG, "Wake up."); - mPowerManager.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE"); - } else if (!wakeEvent && !mDozing) { - if (DEBUG) Log.d(TAG, "Nap time."); - mPowerManager.goToSleep(SystemClock.uptimeMillis(), - PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); - } else if (DEBUG) { - Log.d(TAG, "Skip sensor event. Wake? " + wakeEvent + " dozing: " + mDozing); - } - }); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java index 9a8a6d0c3c3a..6a0e8ad35736 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -16,6 +16,7 @@ package com.android.systemui.keyguard; +import android.annotation.AnyThread; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.PendingIntent; @@ -24,14 +25,20 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.Typeface; +import android.graphics.drawable.Icon; import android.icu.text.DateFormat; import android.icu.text.DisplayContext; +import android.media.MediaMetadata; import android.net.Uri; import android.os.Handler; import android.os.Trace; import android.provider.Settings; import android.service.notification.ZenModeConfig; +import android.text.Spannable; +import android.text.SpannableStringBuilder; import android.text.TextUtils; +import android.text.style.StyleSpan; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; @@ -43,7 +50,9 @@ import androidx.slice.builders.SliceAction; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.NextAlarmControllerImpl; import com.android.systemui.statusbar.policy.ZenModeController; @@ -58,13 +67,17 @@ import java.util.concurrent.TimeUnit; * Simple Slice provider that shows the current date. */ public class KeyguardSliceProvider extends SliceProvider implements - NextAlarmController.NextAlarmChangeCallback, ZenModeController.Callback { + NextAlarmController.NextAlarmChangeCallback, ZenModeController.Callback, + NotificationMediaManager.MediaListener { + private static final StyleSpan BOLD_STYLE = new StyleSpan(Typeface.BOLD); public static final String KEYGUARD_SLICE_URI = "content://com.android.systemui.keyguard/main"; public static final String KEYGUARD_DATE_URI = "content://com.android.systemui.keyguard/date"; public static final String KEYGUARD_NEXT_ALARM_URI = "content://com.android.systemui.keyguard/alarm"; public static final String KEYGUARD_DND_URI = "content://com.android.systemui.keyguard/dnd"; + public static final String KEYGUARD_MEDIA_URI = + "content://com.android.systemui.keyguard/media"; public static final String KEYGUARD_ACTION_URI = "content://com.android.systemui.keyguard/action"; @@ -80,6 +93,7 @@ public class KeyguardSliceProvider extends SliceProvider implements protected final Uri mDateUri; protected final Uri mAlarmUri; protected final Uri mDndUri; + protected final Uri mMediaUri; private final Date mCurrentTime = new Date(); private final Handler mHandler; private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm; @@ -94,6 +108,8 @@ public class KeyguardSliceProvider extends SliceProvider implements protected ContentResolver mContentResolver; private AlarmManager.AlarmClockInfo mNextAlarmInfo; private PendingIntent mPendingIntent; + protected NotificationMediaManager mMediaManager; + protected MediaMetadata mMediaMetaData; /** * Receiver responsible for time ticking and updating the date format. @@ -104,9 +120,13 @@ public class KeyguardSliceProvider extends SliceProvider implements public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_DATE_CHANGED.equals(action)) { - mHandler.post(KeyguardSliceProvider.this::updateClock); + synchronized (this) { + updateClockLocked(); + } } else if (Intent.ACTION_LOCALE_CHANGED.equals(action)) { - mHandler.post(KeyguardSliceProvider.this::cleanDateFormat); + synchronized (this) { + cleanDateFormatLocked(); + } } } }; @@ -116,12 +136,16 @@ public class KeyguardSliceProvider extends SliceProvider implements new KeyguardUpdateMonitorCallback() { @Override public void onTimeChanged() { - mHandler.post(KeyguardSliceProvider.this::updateClock); + synchronized (this) { + updateClockLocked(); + } } @Override public void onTimeZoneChanged(TimeZone timeZone) { - mHandler.post(KeyguardSliceProvider.this::cleanDateFormat); + synchronized (this) { + cleanDateFormatLocked(); + } } }; @@ -140,22 +164,62 @@ public class KeyguardSliceProvider extends SliceProvider implements mDateUri = Uri.parse(KEYGUARD_DATE_URI); mAlarmUri = Uri.parse(KEYGUARD_NEXT_ALARM_URI); mDndUri = Uri.parse(KEYGUARD_DND_URI); + mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI); + } + + public void initDependencies() { + mMediaManager = Dependency.get(NotificationMediaManager.class); + mMediaManager.addCallback(this); } + @AnyThread @Override public Slice onBindSlice(Uri sliceUri) { Trace.beginSection("KeyguardSliceProvider#onBindSlice"); - ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY); - builder.addRow(new RowBuilder(mDateUri).setTitle(mLastText)); - addNextAlarm(builder); - addZenMode(builder); - addPrimaryAction(builder); - Slice slice = builder.build(); + Slice slice; + synchronized (this) { + ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY); + if (mMediaMetaData != null) { + addMediaLocked(builder); + } else { + builder.addRow(new RowBuilder(mDateUri).setTitle(mLastText)); + addNextAlarmLocked(builder); + addZenModeLocked(builder); + } + addPrimaryActionLocked(builder); + slice = builder.build(); + } Trace.endSection(); return slice; } - protected void addPrimaryAction(ListBuilder builder) { + protected void addMediaLocked(ListBuilder listBuilder) { + if (mMediaMetaData != null) { + SpannableStringBuilder builder = new SpannableStringBuilder(); + CharSequence title = mMediaMetaData.getText(MediaMetadata.METADATA_KEY_TITLE); + if (TextUtils.isEmpty(title)) { + title = getContext().getResources().getString(R.string.music_controls_no_title); + } + builder.append(title); + builder.setSpan(BOLD_STYLE, 0, title.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + + CharSequence album = mMediaMetaData.getText(MediaMetadata.METADATA_KEY_ARTIST); + if (!TextUtils.isEmpty(album)) { + builder.append(" ").append(album); + } + + RowBuilder mediaBuilder = new RowBuilder(mMediaUri).setTitle(builder); + Icon notificationIcon = mMediaManager.getMediaIcon(); + if (notificationIcon != null) { + IconCompat icon = IconCompat.createFromIcon(notificationIcon); + mediaBuilder.addEndItem(icon, ListBuilder.ICON_IMAGE); + } + + listBuilder.addRow(mediaBuilder); + } + } + + protected void addPrimaryActionLocked(ListBuilder builder) { // Add simple action because API requires it; Keyguard handles presenting // its own slices so this action + icon are actually never used. IconCompat icon = IconCompat.createWithResource(getContext(), @@ -167,7 +231,7 @@ public class KeyguardSliceProvider extends SliceProvider implements builder.addRow(primaryActionRow); } - protected void addNextAlarm(ListBuilder builder) { + protected void addNextAlarmLocked(ListBuilder builder) { if (TextUtils.isEmpty(mNextAlarm)) { return; } @@ -183,7 +247,7 @@ public class KeyguardSliceProvider extends SliceProvider implements * Add zen mode (DND) icon to slice if it's enabled. * @param builder The slice builder. */ - protected void addZenMode(ListBuilder builder) { + protected void addZenModeLocked(ListBuilder builder) { if (!isDndOn()) { return; } @@ -214,33 +278,35 @@ public class KeyguardSliceProvider extends SliceProvider implements mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0); KeyguardSliceProvider.sInstance = this; registerClockUpdate(); - updateClock(); + updateClockLocked(); return true; } @Override public void onZenChanged(int zen) { - mContentResolver.notifyChange(mSliceUri, null /* observer */); + notifyChange(); } @Override public void onConfigChanged(ZenModeConfig config) { - mContentResolver.notifyChange(mSliceUri, null /* observer */); + notifyChange(); } private void updateNextAlarm() { - if (withinNHours(mNextAlarmInfo, ALARM_VISIBILITY_HOURS)) { - String pattern = android.text.format.DateFormat.is24HourFormat(getContext(), - ActivityManager.getCurrentUser()) ? "HH:mm" : "h:mm"; - mNextAlarm = android.text.format.DateFormat.format(pattern, - mNextAlarmInfo.getTriggerTime()).toString(); - } else { - mNextAlarm = ""; + synchronized (this) { + if (withinNHoursLocked(mNextAlarmInfo, ALARM_VISIBILITY_HOURS)) { + String pattern = android.text.format.DateFormat.is24HourFormat(getContext(), + ActivityManager.getCurrentUser()) ? "HH:mm" : "h:mm"; + mNextAlarm = android.text.format.DateFormat.format(pattern, + mNextAlarmInfo.getTriggerTime()).toString(); + } else { + mNextAlarm = ""; + } } - mContentResolver.notifyChange(mSliceUri, null /* observer */); + notifyChange(); } - private boolean withinNHours(AlarmManager.AlarmClockInfo alarmClockInfo, int hours) { + private boolean withinNHoursLocked(AlarmManager.AlarmClockInfo alarmClockInfo, int hours) { if (alarmClockInfo == null) { return false; } @@ -254,33 +320,37 @@ public class KeyguardSliceProvider extends SliceProvider implements * changing the date/time via the settings app. */ private void registerClockUpdate() { - if (mRegistered) { - return; - } + synchronized (this) { + if (mRegistered) { + return; + } - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_DATE_CHANGED); - filter.addAction(Intent.ACTION_LOCALE_CHANGED); - getContext().registerReceiver(mIntentReceiver, filter, null /* permission*/, - null /* scheduler */); - getKeyguardUpdateMonitor().registerCallback(mKeyguardUpdateMonitorCallback); - mRegistered = true; + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_DATE_CHANGED); + filter.addAction(Intent.ACTION_LOCALE_CHANGED); + getContext().registerReceiver(mIntentReceiver, filter, null /* permission*/, + null /* scheduler */); + getKeyguardUpdateMonitor().registerCallback(mKeyguardUpdateMonitorCallback); + mRegistered = true; + } } @VisibleForTesting boolean isRegistered() { - return mRegistered; + synchronized (this) { + return mRegistered; + } } - protected void updateClock() { - final String text = getFormattedDate(); + protected void updateClockLocked() { + final String text = getFormattedDateLocked(); if (!text.equals(mLastText)) { mLastText = text; - mContentResolver.notifyChange(mSliceUri, null /* observer */); + notifyChange(); } } - protected String getFormattedDate() { + protected String getFormattedDateLocked() { if (mDateFormat == null) { final Locale l = Locale.getDefault(); DateFormat format = DateFormat.getInstanceForSkeleton(mDatePattern, l); @@ -292,20 +362,22 @@ public class KeyguardSliceProvider extends SliceProvider implements } @VisibleForTesting - void cleanDateFormat() { + void cleanDateFormatLocked() { mDateFormat = null; } @Override public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) { - mNextAlarmInfo = nextAlarm; - mAlarmManager.cancel(mUpdateNextAlarm); - - long triggerAt = mNextAlarmInfo == null ? -1 : mNextAlarmInfo.getTriggerTime() - - TimeUnit.HOURS.toMillis(ALARM_VISIBILITY_HOURS); - if (triggerAt > 0) { - mAlarmManager.setExact(AlarmManager.RTC, triggerAt, "lock_screen_next_alarm", - mUpdateNextAlarm, mHandler); + synchronized (this) { + mNextAlarmInfo = nextAlarm; + mAlarmManager.cancel(mUpdateNextAlarm); + + long triggerAt = mNextAlarmInfo == null ? -1 : mNextAlarmInfo.getTriggerTime() + - TimeUnit.HOURS.toMillis(ALARM_VISIBILITY_HOURS); + if (triggerAt > 0) { + mAlarmManager.setExact(AlarmManager.RTC, triggerAt, "lock_screen_next_alarm", + mUpdateNextAlarm, mHandler); + } } updateNextAlarm(); } @@ -314,4 +386,16 @@ public class KeyguardSliceProvider extends SliceProvider implements protected KeyguardUpdateMonitor getKeyguardUpdateMonitor() { return KeyguardUpdateMonitor.getInstance(getContext()); } + + @Override + public void onMetadataChanged(MediaMetadata metadata) { + synchronized (this) { + mMediaMetaData = metadata; + } + notifyChange(); + } + + protected void notifyChange() { + mContentResolver.notifyChange(mSliceUri, null /* observer */); + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index b133346bcf8f..323cf1fe7022 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -445,8 +445,7 @@ public class KeyguardViewMediator extends SystemUI { boolean simWasLocked; synchronized (KeyguardViewMediator.this) { IccCardConstants.State lastState = mLastSimStates.get(slotId); - simWasLocked = (lastState == PIN_REQUIRED || lastState == PUK_REQUIRED) - && simState == READY; + simWasLocked = (lastState == PIN_REQUIRED || lastState == PUK_REQUIRED); mLastSimStates.append(slotId, simState); } @@ -471,6 +470,8 @@ public class KeyguardViewMediator extends SystemUI { // so we should only lock when they are ABSENT. onSimAbsentLocked(); if (simWasLocked) { + if (DEBUG_SIM_STATES) Log.d(TAG, "SIM moved to ABSENT when the " + + "previous state was locked. Reset the state."); resetStateLocked(); } } @@ -507,6 +508,8 @@ public class KeyguardViewMediator extends SystemUI { synchronized (KeyguardViewMediator.this) { if (DEBUG_SIM_STATES) Log.d(TAG, "READY, reset state? " + mShowing); if (mShowing && simWasLocked) { + if (DEBUG_SIM_STATES) Log.d(TAG, "SIM moved to READY when the " + + "previous state was locked. Reset the state."); resetStateLocked(); } mLockWhenSimRemoved = true; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java index b6fce4408bcf..834bca55103a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java @@ -23,9 +23,13 @@ import com.android.systemui.Dumpable; import java.io.FileDescriptor; import java.io.PrintWriter; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Tracks the screen lifecycle. */ +@Singleton public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> implements Dumpable { public static final int SCREEN_OFF = 0; @@ -35,6 +39,10 @@ public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> impleme private int mScreenState = SCREEN_OFF; + @Inject + public ScreenLifecycle() { + } + public int getScreenState() { return mScreenState; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java index 59c7f236caf7..52a0214c492c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java @@ -23,9 +23,13 @@ import com.android.systemui.Dumpable; import java.io.FileDescriptor; import java.io.PrintWriter; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Tracks the wakefulness lifecycle. */ +@Singleton public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements Dumpable { @@ -36,6 +40,10 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe private int mWakefulness = WAKEFULNESS_ASLEEP; + @Inject + public WakefulnessLifecycle() { + } + public int getWakefulness() { return mWakefulness; } diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java index 03daa95567ee..69495319e060 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java @@ -20,11 +20,20 @@ import com.android.systemui.Dependency; import com.android.systemui.plugins.PluginDependency.DependencyProvider; import com.android.systemui.shared.plugins.PluginManager; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class PluginDependencyProvider extends DependencyProvider { private final ArrayMap<Class<?>, Object> mDependencies = new ArrayMap<>(); private final PluginManager mManager; + /** + */ + @Inject public PluginDependencyProvider(PluginManager manager) { mManager = manager; PluginDependency.sProvider = this; diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index b722f9f1d1c1..50dda1c1de6b 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -58,6 +58,12 @@ import java.text.NumberFormat; import java.util.Locale; import java.util.Objects; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class PowerNotificationWarnings implements PowerUI.WarningsUI { private static final String TAG = PowerUI.TAG + ".Notification"; private static final boolean DEBUG = PowerUI.DEBUG; @@ -136,6 +142,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private SystemUIDialog mHighTempDialog; private SystemUIDialog mThermalShutdownDialog; + /** + */ + @Inject public PowerNotificationWarnings(Context context) { mContext = context; mNoMan = mContext.getSystemService(NotificationManager.class); diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt index 519df19f0e20..2894621e7775 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt @@ -29,7 +29,9 @@ class PrivacyDialogBuilder(val context: Context, itemsList: List<PrivacyItem>) { init { appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType }) .toList() - .sortedWith(compareBy({ -it.second.size }, { it.first })) + .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps + { it.second.min() }, // Sort by "smallest" AppOpp (Location is largest) + { it.first })) // Sort alphabetically bt App Name types = itemsList.map { it.privacyType }.distinct().sorted() val singleApp = appsAndTypes.size == 1 app = if (singleApp) appsAndTypes[0].first else null diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt index 2c4da64712ac..9252167d02bd 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt @@ -24,8 +24,8 @@ typealias Privacy = PrivacyType enum class PrivacyType(val nameId: Int, val iconId: Int) { TYPE_CAMERA(R.string.privacy_type_camera, R.drawable.stat_sys_camera), - TYPE_LOCATION(R.string.privacy_type_location, R.drawable.stat_sys_location), - TYPE_MICROPHONE(R.string.privacy_type_microphone, R.drawable.stat_sys_mic_none); + TYPE_MICROPHONE(R.string.privacy_type_microphone, R.drawable.stat_sys_mic_none), + TYPE_LOCATION(R.string.privacy_type_location, R.drawable.stat_sys_location); fun getName(context: Context) = context.resources.getString(nameId) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index aba9bb804619..e63f88a898cc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -18,6 +18,8 @@ package com.android.systemui.qs; import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS; +import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; + import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; @@ -48,7 +50,6 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.Utils; import com.android.settingslib.drawable.UserIconDrawable; import com.android.settingslib.graph.SignalDrawable; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.R.dimen; import com.android.systemui.plugins.ActivityStarter; @@ -63,11 +64,16 @@ import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; import com.android.systemui.tuner.TunerService; +import javax.inject.Inject; +import javax.inject.Named; + public class QSFooterImpl extends FrameLayout implements QSFooter, OnClickListener, OnUserInfoChangedListener, EmergencyListener, SignalCallback { - private ActivityStarter mActivityStarter; - private UserInfoController mUserInfoController; + private final ActivityStarter mActivityStarter; + private final UserInfoController mUserInfoController; + private final NetworkController mNetworkController; + private final DeviceProvisionedController mDeviceProvisionedController; private SettingsButton mSettingsButton; protected View mSettingsContainer; private PageIndicator mPageIndicator; @@ -100,9 +106,17 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private final CellSignalState mInfo = new CellSignalState(); private OnClickListener mExpandClickListener; - public QSFooterImpl(Context context, AttributeSet attrs) { + @Inject + public QSFooterImpl(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, + ActivityStarter activityStarter, UserInfoController userInfoController, + NetworkController networkController, + DeviceProvisionedController deviceProvisionedController) { super(context, attrs); mColorForeground = Utils.getColorAttrDefaultColor(context, android.R.attr.colorForeground); + mActivityStarter = activityStarter; + mUserInfoController = userInfoController; + mNetworkController = networkController; + mDeviceProvisionedController = deviceProvisionedController; } @Override @@ -111,7 +125,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, mDivider = findViewById(R.id.qs_footer_divider); mEdit = findViewById(android.R.id.edit); mEdit.setOnClickListener(view -> - Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> + mActivityStarter.postQSRunnableDismissingKeyguard(() -> mQsPanel.showEdit(view))); mPageIndicator = findViewById(R.id.footer_page_indicator); @@ -137,8 +151,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, updateResources(); - mUserInfoController = Dependency.get(UserInfoController.class); - mActivityStarter = Dependency.get(ActivityStarter.class); addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> updateAnimator(right - left)); setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); @@ -316,14 +328,14 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private void updateListeners() { if (mListening) { mUserInfoController.addCallback(this); - if (Dependency.get(NetworkController.class).hasVoiceCallingFeature()) { - Dependency.get(NetworkController.class).addEmergencyListener(this); - Dependency.get(NetworkController.class).addCallback(this); + if (mNetworkController.hasVoiceCallingFeature()) { + mNetworkController.addEmergencyListener(this); + mNetworkController.addCallback(this); } } else { mUserInfoController.removeCallback(this); - Dependency.get(NetworkController.class).removeEmergencyListener(this); - Dependency.get(NetworkController.class).removeCallback(this); + mNetworkController.removeEmergencyListener(this); + mNetworkController.removeCallback(this); } } @@ -344,7 +356,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, } if (v == mSettingsButton) { - if (!Dependency.get(DeviceProvisionedController.class).isCurrentUserSetup()) { + if (!mDeviceProvisionedController.isCurrentUserSetup()) { // If user isn't setup just unlock the device and dump them back at SUW. mActivityStarter.postQSRunnableDismissingKeyguard(() -> { }); return; @@ -353,7 +365,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH : MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH); if (mSettingsButton.isTunerClick()) { - Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> { + mActivityStarter.postQSRunnableDismissingKeyguard(() -> { if (TunerService.isTunerEnabled(mContext)) { TunerService.showResetRequest(mContext, () -> { // Relaunch settings so that the tuner disappears. diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 93130d4667d0..34d30fe58404 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -18,7 +18,7 @@ import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.app.Fragment; +import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; @@ -46,10 +46,11 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.util.InjectionInflationController; +import com.android.systemui.util.LifecycleFragment; import javax.inject.Inject; -public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks { +public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Callbacks { private static final String TAG = "QS"; private static final boolean DEBUG = false; private static final String EXTRA_EXPANDED = "expanded"; @@ -78,12 +79,18 @@ public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks { private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private final InjectionInflationController mInjectionInflater; + private final QSTileHost mHost; @Inject public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler, - InjectionInflationController injectionInflater) { + InjectionInflationController injectionInflater, + Context context, + QSTileHost qsTileHost) { mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler; mInjectionInflater = injectionInflater; + SysUiServiceProvider.getComponent(context, CommandQueue.class) + .observe(getLifecycle(), this); + mHost = qsTileHost; } @Override @@ -118,13 +125,7 @@ public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks { mQSPanel.getTileLayout().restoreInstanceState(savedInstanceState); } } - SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallback(this); - } - - @Override - public void onDestroyView() { - SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallback(this); - super.onDestroyView(); + setHost(mHost); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index d7d3981d05d1..7c937a944113 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -17,6 +17,7 @@ package com.android.systemui.qs; import android.app.ActivityManager; import android.app.AlertDialog; +import android.app.admin.DevicePolicyEventLogger; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -30,6 +31,7 @@ import android.text.SpannableStringBuilder; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.util.Log; +import android.util.StatsLog; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; @@ -119,6 +121,9 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic private void handleClick() { showDeviceMonitoringDialog(); + DevicePolicyEventLogger + .createEvent(StatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED) + .write(); } public void showDeviceMonitoringDialog() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index ca8e824a223f..3a6b785eb9b5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.os.Handler; +import android.os.Looper; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -30,6 +31,7 @@ import android.util.Log; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.qs.QSFactory; import com.android.systemui.plugins.qs.QSTile; @@ -52,7 +54,12 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.function.Predicate; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + /** Platform implementation of the quick settings tile host **/ +@Singleton public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> { private static final String TAG = "QSTileHost"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -60,29 +67,44 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> { public static final String TILES_SETTING = Secure.QS_TILES; private final Context mContext; - private final StatusBar mStatusBar; private final LinkedHashMap<String, QSTile> mTiles = new LinkedHashMap<>(); protected final ArrayList<String> mTileSpecs = new ArrayList<>(); private final TileServices mServices; + private final TunerService mTunerService; + private final PluginManager mPluginManager; private final List<Callback> mCallbacks = new ArrayList<>(); private final AutoTileManager mAutoTiles; private final StatusBarIconController mIconController; private final ArrayList<QSFactory> mQsFactories = new ArrayList<>(); private int mCurrentUser; - - public QSTileHost(Context context, StatusBar statusBar, - StatusBarIconController iconController) { + private StatusBar mStatusBar; + + @Inject + public QSTileHost(Context context, + StatusBarIconController iconController, + QSFactoryImpl defaultFactory, + @Named(Dependency.MAIN_HANDLER_NAME) Handler mainHandler, + @Named(Dependency.BG_LOOPER_NAME) Looper bgLooper, + PluginManager pluginManager, + TunerService tunerService) { mIconController = iconController; mContext = context; - mStatusBar = statusBar; + mTunerService = tunerService; + mPluginManager = pluginManager; - mServices = new TileServices(this, Dependency.get(Dependency.BG_LOOPER)); + mServices = new TileServices(this, bgLooper); - mQsFactories.add(new QSFactoryImpl(this)); - Dependency.get(PluginManager.class).addPluginListener(this, QSFactory.class, true); + defaultFactory.setHost(this); + mQsFactories.add(defaultFactory); + pluginManager.addPluginListener(this, QSFactory.class, true); - Dependency.get(TunerService.class).addTunable(this, TILES_SETTING); + mainHandler.post(() -> { + // This is technically a hack to avoid circular dependency of + // QSTileHost -> XXXTile -> QSTileHost. Posting ensures creation + // finishes before creating any tiles. + tunerService.addTunable(this, TILES_SETTING); + }); // AutoTileManager can modify mTiles so make sure mTiles has already been initialized. mAutoTiles = new AutoTileManager(context, this); } @@ -94,16 +116,16 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> { public void destroy() { mTiles.values().forEach(tile -> tile.destroy()); mAutoTiles.destroy(); - Dependency.get(TunerService.class).removeTunable(this); + mTunerService.removeTunable(this); mServices.destroy(); - Dependency.get(PluginManager.class).removePluginListener(this); + mPluginManager.removePluginListener(this); } @Override public void onPluginConnected(QSFactory plugin, Context pluginContext) { // Give plugins priority over creation so they can override if they wish. mQsFactories.add(0, plugin); - String value = Dependency.get(TunerService.class).getValue(TILES_SETTING); + String value = mTunerService.getValue(TILES_SETTING); // Force remove and recreate of all tiles. onTuningChanged(TILES_SETTING, ""); onTuningChanged(TILES_SETTING, value); @@ -113,7 +135,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> { public void onPluginDisconnected(QSFactory plugin) { mQsFactories.remove(plugin); // Force remove and recreate of all tiles. - String value = Dependency.get(TunerService.class).getValue(TILES_SETTING); + String value = mTunerService.getValue(TILES_SETTING); onTuningChanged(TILES_SETTING, ""); onTuningChanged(TILES_SETTING, value); } @@ -140,16 +162,25 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> { @Override public void collapsePanels() { + if (mStatusBar == null) { + mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class); + } mStatusBar.postAnimateCollapsePanels(); } @Override public void forceCollapsePanels() { + if (mStatusBar == null) { + mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class); + } mStatusBar.postAnimateForceCollapsePanels(); } @Override public void openPanels() { + if (mStatusBar == null) { + mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class); + } mStatusBar.postAnimateOpenPanels(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index bec027f902a0..72245999b084 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -63,6 +63,8 @@ import com.android.systemui.BatteryMeterView; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.privacy.OngoingPrivacyChip; import com.android.systemui.privacy.OngoingPrivacyDialog; import com.android.systemui.privacy.PrivacyItem; @@ -75,8 +77,6 @@ import com.android.systemui.statusbar.phone.StatusIconContainer; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.Clock; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.DateView; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.ZenModeController; 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 fd2c4e35e49b..d26cee982b64 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java @@ -47,12 +47,79 @@ import com.android.systemui.qs.tiles.WifiTile; import com.android.systemui.qs.tiles.WorkModeTile; import com.android.systemui.util.leak.GarbageMonitor; +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; + +@Singleton public class QSFactoryImpl implements QSFactory { private static final String TAG = "QSFactory"; - private final QSTileHost mHost; - public QSFactoryImpl(QSTileHost host) { + private final Provider<WifiTile> mWifiTileProvider; + private final Provider<BluetoothTile> mBluetoothTileProvider; + private final Provider<CellularTile> mCellularTileProvider; + private final Provider<DndTile> mDndTileProvider; + private final Provider<ColorInversionTile> mColorInversionTileProvider; + private final Provider<AirplaneModeTile> mAirplaneModeTileProvider; + private final Provider<WorkModeTile> mWorkModeTileProvider; + private final Provider<RotationLockTile> mRotationLockTileProvider; + private final Provider<FlashlightTile> mFlashlightTileProvider; + private final Provider<LocationTile> mLocationTileProvider; + private final Provider<CastTile> mCastTileProvider; + private final Provider<HotspotTile> mHotspotTileProvider; + private final Provider<UserTile> mUserTileProvider; + private final Provider<BatterySaverTile> mBatterySaverTileProvider; + 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; + + @Inject + public QSFactoryImpl(Provider<WifiTile> wifiTileProvider, + Provider<BluetoothTile> bluetoothTileProvider, + Provider<CellularTile> cellularTileProvider, + Provider<DndTile> dndTileProvider, + Provider<ColorInversionTile> colorInversionTileProvider, + Provider<AirplaneModeTile> airplaneModeTileProvider, + Provider<WorkModeTile> workModeTileProvider, + Provider<RotationLockTile> rotationLockTileProvider, + Provider<FlashlightTile> flashlightTileProvider, + Provider<LocationTile> locationTileProvider, + Provider<CastTile> castTileProvider, + Provider<HotspotTile> hotspotTileProvider, + Provider<UserTile> userTileProvider, + Provider<BatterySaverTile> batterySaverTileProvider, + Provider<DataSaverTile> dataSaverTileProvider, + Provider<NightDisplayTile> nightDisplayTileProvider, + Provider<NfcTile> nfcTileProvider, + Provider<SensorPrivacyTile> sensorPrivacyTileProvider, + Provider<GarbageMonitor.MemoryTile> memoryTileProvider) { + mWifiTileProvider = wifiTileProvider; + mBluetoothTileProvider = bluetoothTileProvider; + mCellularTileProvider = cellularTileProvider; + mDndTileProvider = dndTileProvider; + mColorInversionTileProvider = colorInversionTileProvider; + mAirplaneModeTileProvider = airplaneModeTileProvider; + mWorkModeTileProvider = workModeTileProvider; + mRotationLockTileProvider = rotationLockTileProvider; + mFlashlightTileProvider = flashlightTileProvider; + mLocationTileProvider = locationTileProvider; + mCastTileProvider = castTileProvider; + mHotspotTileProvider = hotspotTileProvider; + mUserTileProvider = userTileProvider; + mBatterySaverTileProvider = batterySaverTileProvider; + mDataSaverTileProvider = dataSaverTileProvider; + mNightDisplayTileProvider = nightDisplayTileProvider; + mNfcTileProvider = nfcTileProvider; + mSensorPrivacyTileProvider = sensorPrivacyTileProvider; + mMemoryTileProvider = memoryTileProvider; + } + + public void setHost(QSTileHost host) { mHost = host; } @@ -68,41 +135,41 @@ public class QSFactoryImpl implements QSFactory { // Stock tiles. switch (tileSpec) { case "wifi": - return new WifiTile(mHost); + return mWifiTileProvider.get(); case "bt": - return new BluetoothTile(mHost); + return mBluetoothTileProvider.get(); case "cell": - return new CellularTile(mHost); + return mCellularTileProvider.get(); case "dnd": - return new DndTile(mHost); + return mDndTileProvider.get(); case "inversion": - return new ColorInversionTile(mHost); + return mColorInversionTileProvider.get(); case "airplane": - return new AirplaneModeTile(mHost); + return mAirplaneModeTileProvider.get(); case "work": - return new WorkModeTile(mHost); + return mWorkModeTileProvider.get(); case "rotation": - return new RotationLockTile(mHost); + return mRotationLockTileProvider.get(); case "flashlight": - return new FlashlightTile(mHost); + return mFlashlightTileProvider.get(); case "location": - return new LocationTile(mHost); + return mLocationTileProvider.get(); case "cast": - return new CastTile(mHost); + return mCastTileProvider.get(); case "hotspot": - return new HotspotTile(mHost); + return mHotspotTileProvider.get(); case "user": - return new UserTile(mHost); + return mUserTileProvider.get(); case "battery": - return new BatterySaverTile(mHost); + return mBatterySaverTileProvider.get(); case "saver": - return new DataSaverTile(mHost); + return mDataSaverTileProvider.get(); case "night": - return new NightDisplayTile(mHost); + return mNightDisplayTileProvider.get(); case "nfc": - return new NfcTile(mHost); + return mNfcTileProvider.get(); case "sensorprivacy": - return new SensorPrivacyTile(mHost); + return mSensorPrivacyTileProvider.get(); } // Intent tiles. @@ -112,7 +179,7 @@ public class QSFactoryImpl implements QSFactory { // Debug tiles. if (Build.IS_DEBUGGABLE) { if (tileSpec.equals(GarbageMonitor.MemoryTile.TILE_SPEC)) { - return new GarbageMonitor.MemoryTile(mHost); + return mMemoryTileProvider.get(); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index cc27135ce1e1..e1a43785b5c4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -14,6 +14,9 @@ package com.android.systemui.qs.tileimpl; +import static androidx.lifecycle.Lifecycle.State.DESTROYED; +import static androidx.lifecycle.Lifecycle.State.RESUMED; + import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK; @@ -38,6 +41,11 @@ import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; +import androidx.annotation.NonNull; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.LifecycleRegistry; + import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.settingslib.RestrictedLockUtils; @@ -66,7 +74,7 @@ import java.util.ArrayList; * * @param <TState> see above */ -public abstract class QSTileImpl<TState extends State> implements QSTile { +public abstract class QSTileImpl<TState extends State> implements QSTile, LifecycleOwner { protected final String TAG = "Tile." + getClass().getSimpleName(); protected static final boolean DEBUG = Log.isLoggable("Tile", Log.DEBUG); @@ -94,6 +102,8 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { private boolean mShowingDetail; private int mIsFullQs; + private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this); + public abstract TState newTileState(); abstract protected void handleClick(); @@ -113,6 +123,12 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { mContext = host.getContext(); } + @NonNull + @Override + public Lifecycle getLifecycle() { + return mLifecycle; + } + /** * Adds or removes a listening client for the tile. If the tile has one or more * listening client it will go into the listening state. @@ -341,12 +357,14 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { if (listening) { if (mListeners.add(listener) && mListeners.size() == 1) { if (DEBUG) Log.d(TAG, "handleSetListening true"); + mLifecycle.markState(RESUMED); handleSetListening(listening); refreshState(); // Ensure we get at least one refresh after listening. } } else { if (mListeners.remove(listener) && mListeners.size() == 0) { if (DEBUG) Log.d(TAG, "handleSetListening false"); + mLifecycle.markState(DESTROYED); handleSetListening(listening); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index c8c2158dc4e1..387de716844c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -32,7 +32,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; @@ -40,16 +39,21 @@ import com.android.systemui.qs.GlobalSetting; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; +import javax.inject.Inject; + /** Quick settings tile: Airplane mode **/ public class AirplaneModeTile extends QSTileImpl<BooleanState> { private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_airplane); private final GlobalSetting mSetting; + private final ActivityStarter mActivityStarter; private boolean mListening; - public AirplaneModeTile(QSHost host) { + @Inject + public AirplaneModeTile(QSHost host, ActivityStarter activityStarter) { super(host); + mActivityStarter = activityStarter; mSetting = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) { @Override @@ -70,7 +74,7 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> { MetricsLogger.action(mContext, getMetricsCategory(), !airplaneModeEnabled); if (!airplaneModeEnabled && Boolean.parseBoolean( SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) { - Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard( + mActivityStarter.postStartActivityDismissingKeyguard( new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS), 0); return; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index da2828eae7da..7f76900bba21 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -23,13 +23,14 @@ import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.graph.BatteryMeterDrawableBase; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile.BooleanState; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.BatteryController; +import javax.inject.Inject; + public class BatterySaverTile extends QSTileImpl<BooleanState> implements BatteryController.BatteryStateChangeCallback { @@ -40,9 +41,11 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements private boolean mCharging; private boolean mPluggedIn; - public BatterySaverTile(QSHost host) { + @Inject + public BatterySaverTile(QSHost host, BatteryController batteryController) { super(host); - mBatteryController = Dependency.get(BatteryController.class); + mBatteryController = batteryController; + mBatteryController.observe(getLifecycle(), this); } @Override @@ -57,11 +60,6 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements @Override public void handleSetListening(boolean listening) { - if (listening) { - mBatteryController.addCallback(this); - } else { - mBatteryController.removeCallback(this); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 3ab1c21b5066..5b85498574a7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -36,7 +36,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.graph.BluetoothDeviceLayerDrawable; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; @@ -51,6 +50,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import javax.inject.Inject; + /** Quick settings tile: Bluetooth **/ public class BluetoothTile extends QSTileImpl<BooleanState> { private static final Intent BLUETOOTH_SETTINGS = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); @@ -59,11 +60,15 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { private final BluetoothDetailAdapter mDetailAdapter; private final ActivityStarter mActivityStarter; - public BluetoothTile(QSHost host) { + @Inject + public BluetoothTile(QSHost host, + BluetoothController bluetoothController, + ActivityStarter activityStarter) { super(host); - mController = Dependency.get(BluetoothController.class); - mActivityStarter = Dependency.get(ActivityStarter.class); + mController = bluetoothController; + mActivityStarter = activityStarter; mDetailAdapter = (BluetoothDetailAdapter) createDetailAdapter(); + mController.observe(getLifecycle(), mCallback); } @Override @@ -78,11 +83,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { - if (listening) { - mController.addCallback(mCallback); - } else { - mController.removeCallback(mCallback); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 921db6901626..f05ac4c107eb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -33,7 +33,6 @@ import android.widget.Button; import com.android.internal.app.MediaRouteDialogPresenter; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; @@ -51,6 +50,8 @@ import com.android.systemui.statusbar.policy.NetworkController; import java.util.LinkedHashMap; import java.util.Set; +import javax.inject.Inject; + /** Quick settings tile: Cast **/ public class CastTile extends QSTileImpl<BooleanState> { private static final Intent CAST_SETTINGS = @@ -65,13 +66,18 @@ public class CastTile extends QSTileImpl<BooleanState> { private Dialog mDialog; private boolean mWifiConnected; - public CastTile(QSHost host) { + @Inject + public CastTile(QSHost host, CastController castController, KeyguardMonitor keyguardMonitor, + NetworkController networkController, ActivityStarter activityStarter) { super(host); - mController = Dependency.get(CastController.class); + mController = castController; mDetailAdapter = new CastDetailAdapter(); - mKeyguard = Dependency.get(KeyguardMonitor.class); - mNetworkController = Dependency.get(NetworkController.class); - mActivityStarter = Dependency.get(ActivityStarter.class); + mKeyguard = keyguardMonitor; + mNetworkController = networkController; + mActivityStarter = activityStarter; + mController.observe(this, mCallback); + mKeyguard.observe(this, mCallback); + mNetworkController.observe(this, mSignalCallback); } @Override @@ -87,15 +93,8 @@ public class CastTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { if (DEBUG) Log.d(TAG, "handleSetListening " + listening); - if (listening) { - mController.addCallback(mCallback); - mKeyguard.addCallback(mCallback); - mNetworkController.addCallback(mSignalCallback); - } else { + if (!listening) { mController.setDiscovering(false); - mController.removeCallback(mCallback); - mKeyguard.removeCallback(mCallback); - mNetworkController.removeCallback(mSignalCallback); } } @@ -135,7 +134,7 @@ public class CastTile extends QSTileImpl<BooleanState> { mDialog = MediaRouteDialogPresenter.createDialog(mContext, ROUTE_TYPE_REMOTE_DISPLAY, v -> { mDialog.dismiss(); - Dependency.get(ActivityStarter.class) + mActivityStarter .postStartActivityDismissingKeyguard(getLongClickIntent(), 0); }); mDialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 9e341e298821..1155a414b870 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -35,7 +35,6 @@ import android.widget.Switch; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.net.DataUsageController; -import com.android.systemui.Dependency; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; @@ -51,6 +50,8 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import javax.inject.Inject; + /** Quick settings tile: Cellular **/ public class CellularTile extends QSTileImpl<SignalState> { private static final String ENABLE_SETTINGS_DATA_PLAN = "enable.settings.data.plan"; @@ -63,13 +64,16 @@ public class CellularTile extends QSTileImpl<SignalState> { private final ActivityStarter mActivityStarter; private final KeyguardMonitor mKeyguardMonitor; - public CellularTile(QSHost host) { + @Inject + public CellularTile(QSHost host, NetworkController networkController, + ActivityStarter activityStarter, KeyguardMonitor keyguardMonitor) { super(host); - mController = Dependency.get(NetworkController.class); - mActivityStarter = Dependency.get(ActivityStarter.class); - mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); + mController = networkController; + mActivityStarter = activityStarter; + mKeyguardMonitor = keyguardMonitor; mDataController = mController.getMobileDataController(); mDetailAdapter = new CellularDetailAdapter(); + mController.observe(getLifecycle(), mSignalCallback); } @Override @@ -84,11 +88,6 @@ public class CellularTile extends QSTileImpl<SignalState> { @Override public void handleSetListening(boolean listening) { - if (listening) { - mController.addCallback(mSignalCallback); - } else { - mController.removeCallback(mSignalCallback); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index c13a07fdd15e..ecb4048b148d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -30,6 +30,8 @@ import com.android.systemui.qs.QSHost; import com.android.systemui.qs.SecureSetting; import com.android.systemui.qs.tileimpl.QSTileImpl; +import javax.inject.Inject; + /** Quick settings tile: Invert colors **/ public class ColorInversionTile extends QSTileImpl<BooleanState> { @@ -38,6 +40,7 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> { private boolean mListening; + @Inject public ColorInversionTile(QSHost host) { super(host); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index fd8b9c9534dc..c6c6f877ac9b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -20,7 +20,6 @@ import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile.BooleanState; @@ -30,14 +29,18 @@ import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.NetworkController; +import javax.inject.Inject; + public class DataSaverTile extends QSTileImpl<BooleanState> implements DataSaverController.Listener{ private final DataSaverController mDataSaverController; - public DataSaverTile(QSHost host) { + @Inject + public DataSaverTile(QSHost host, NetworkController networkController) { super(host); - mDataSaverController = Dependency.get(NetworkController.class).getDataSaverController(); + mDataSaverController = networkController.getDataSaverController(); + mDataSaverController.observe(getLifecycle(), this); } @Override @@ -47,11 +50,6 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements @Override public void handleSetListening(boolean listening) { - if (listening) { - mDataSaverController.addCallback(this); - } else { - mDataSaverController.removeCallback(this); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 50c8698db2c7..5f04e56f28a4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -49,7 +49,6 @@ import android.widget.Toast; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.notification.EnableZenModeDialog; -import com.android.systemui.Dependency; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.SysUIToast; @@ -62,6 +61,8 @@ import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.volume.ZenModePanel; +import javax.inject.Inject; + /** Quick settings tile: Do not disturb **/ public class DndTile extends QSTileImpl<BooleanState> { @@ -76,17 +77,22 @@ public class DndTile extends QSTileImpl<BooleanState> { private final ZenModeController mController; private final DndDetailAdapter mDetailAdapter; + private final ActivityStarter mActivityStarter; private boolean mListening; private boolean mShowingDetail; private boolean mReceiverRegistered; - public DndTile(QSHost host) { + @Inject + public DndTile(QSHost host, ZenModeController zenModeController, + ActivityStarter activityStarter) { super(host); - mController = Dependency.get(ZenModeController.class); + mController = zenModeController; + mActivityStarter = activityStarter; mDetailAdapter = new DndDetailAdapter(); mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE)); mReceiverRegistered = true; + mController.observe(getLifecycle(), mZenCallback); } @Override @@ -157,7 +163,7 @@ public class DndTile extends QSTileImpl<BooleanState> { // show on-boarding screen Intent intent = new Intent(Settings.ZEN_MODE_ONBOARDING); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(intent, 0); + mActivityStarter.postStartActivityDismissingKeyguard(intent, 0); } else { switch (zenDuration) { case Settings.Secure.ZEN_DURATION_PROMPT: @@ -281,10 +287,8 @@ public class DndTile extends QSTileImpl<BooleanState> { if (mListening == listening) return; mListening = listening; if (mListening) { - mController.addCallback(mZenCallback); Prefs.registerListener(mContext, mPrefListener); } else { - mController.removeCallback(mZenCallback); Prefs.unregisterListener(mContext, mPrefListener); } } @@ -445,7 +449,7 @@ public class DndTile extends QSTileImpl<BooleanState> { private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() { @Override public void onPrioritySettings() { - Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard( + mActivityStarter.postStartActivityDismissingKeyguard( ZEN_PRIORITY_SETTINGS, 0); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index d7ac2532982d..dfa3fb9dafc9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -23,13 +23,14 @@ import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.R; 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.FlashlightController; +import javax.inject.Inject; + /** Quick settings tile: Control flashlight **/ public class FlashlightTile extends QSTileImpl<BooleanState> implements FlashlightController.FlashlightListener { @@ -37,9 +38,11 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight); private final FlashlightController mFlashlightController; - public FlashlightTile(QSHost host) { + @Inject + public FlashlightTile(QSHost host, FlashlightController flashlightController) { super(host); - mFlashlightController = Dependency.get(FlashlightController.class); + mFlashlightController = flashlightController; + mFlashlightController.observe(getLifecycle(), this); } @Override @@ -56,11 +59,6 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements @Override public void handleSetListening(boolean listening) { - if (listening) { - mFlashlightController.addCallback(this); - } else { - mFlashlightController.removeCallback(this); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 6bf0793a69cb..b7e07f828321 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -25,7 +25,6 @@ import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile.AirplaneBooleanState; import com.android.systemui.qs.GlobalSetting; @@ -34,6 +33,8 @@ import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.HotspotController; +import javax.inject.Inject; + /** Quick settings tile: Hotspot **/ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> { private static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName( @@ -48,16 +49,20 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> { private final GlobalSetting mAirplaneMode; private boolean mListening; - public HotspotTile(QSHost host) { + @Inject + public HotspotTile(QSHost host, HotspotController hotspotController, + DataSaverController dataSaverController) { super(host); - mHotspotController = Dependency.get(HotspotController.class); - mDataSaverController = Dependency.get(DataSaverController.class); + mHotspotController = hotspotController; + mDataSaverController = dataSaverController; mAirplaneMode = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) { @Override protected void handleValueChanged(int value) { refreshState(); } }; + mHotspotController.observe(this, mCallbacks); + mDataSaverController.observe(this, mCallbacks); } @Override @@ -80,12 +85,7 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> { if (mListening == listening) return; mListening = listening; if (listening) { - mHotspotController.addCallback(mCallbacks); - mDataSaverController.addCallback(mCallbacks); refreshState(); - } else { - mHotspotController.removeCallback(mCallbacks); - mDataSaverController.removeCallback(mCallbacks); } mAirplaneMode.setListening(listening); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index b5f2d005e8e4..d740033c9f48 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -23,7 +23,6 @@ import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.R.drawable; import com.android.systemui.plugins.ActivityStarter; @@ -34,6 +33,8 @@ import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback; +import javax.inject.Inject; + /** Quick settings tile: Location **/ public class LocationTile extends QSTileImpl<BooleanState> { @@ -41,12 +42,18 @@ public class LocationTile extends QSTileImpl<BooleanState> { private final LocationController mController; private final KeyguardMonitor mKeyguard; + private final ActivityStarter mActivityStarter; private final Callback mCallback = new Callback(); - public LocationTile(QSHost host) { + @Inject + public LocationTile(QSHost host, LocationController locationController, + KeyguardMonitor keyguardMonitor, ActivityStarter activityStarter) { super(host); - mController = Dependency.get(LocationController.class); - mKeyguard = Dependency.get(KeyguardMonitor.class); + mController = locationController; + mKeyguard = keyguardMonitor; + mActivityStarter = activityStarter; + mController.observe(this, mCallback); + mKeyguard.observe(this, mCallback); } @Override @@ -56,13 +63,6 @@ public class LocationTile extends QSTileImpl<BooleanState> { @Override public void handleSetListening(boolean listening) { - if (listening) { - mController.addCallback(mCallback); - mKeyguard.addCallback(mCallback); - } else { - mController.removeCallback(mCallback); - mKeyguard.removeCallback(mCallback); - } } @Override @@ -73,7 +73,7 @@ public class LocationTile extends QSTileImpl<BooleanState> { @Override protected void handleClick() { if (mKeyguard.isSecure() && mKeyguard.isShowing()) { - Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> { + mActivityStarter.postQSRunnableDismissingKeyguard(() -> { final boolean wasEnabled = mState.value; mHost.openPanels(); mController.setLocationEnabled(!wasEnabled); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index a365e4c53b0d..476a239de721 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -33,6 +33,8 @@ import com.android.systemui.plugins.qs.QSTile.BooleanState; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; +import javax.inject.Inject; + /** Quick settings tile: Enable/Disable NFC **/ public class NfcTile extends QSTileImpl<BooleanState> { @@ -40,6 +42,7 @@ public class NfcTile extends QSTileImpl<BooleanState> { private boolean mListening; + @Inject public NfcTile(QSHost host) { super(host); } 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 90890c076a3c..b04132d09b7c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -44,6 +44,8 @@ import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.TimeZone; +import javax.inject.Inject; + public class NightDisplayTile extends QSTileImpl<BooleanState> implements ColorDisplayController.Callback { @@ -58,6 +60,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> private ColorDisplayController mController; private boolean mIsListening; + @Inject public NightDisplayTile(QSHost host) { super(host); mController = new ColorDisplayController(mContext, ActivityManager.getCurrentUser()); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 634581638c32..21f3d6e77f7b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -24,7 +24,6 @@ import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile.BooleanState; import com.android.systemui.qs.QSHost; @@ -32,15 +31,19 @@ import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; +import javax.inject.Inject; + /** Quick settings tile: Rotation **/ public class RotationLockTile extends QSTileImpl<BooleanState> { private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_auto_rotate); private final RotationLockController mController; - public RotationLockTile(QSHost host) { + @Inject + public RotationLockTile(QSHost host, RotationLockController rotationLockController) { super(host); - mController = Dependency.get(RotationLockController.class); + mController = rotationLockController; + mController.observe(this, mCallback); } @Override @@ -49,11 +52,6 @@ public class RotationLockTile extends QSTileImpl<BooleanState> { } public void handleSetListening(boolean listening) { - if (listening) { - mController.addCallback(mCallback); - } else { - mController.removeCallback(mCallback); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java index ff368f80d06a..5230cea88e8e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyTile.java @@ -23,7 +23,6 @@ import android.widget.Switch; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.BooleanState; @@ -31,6 +30,8 @@ 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 { @@ -39,12 +40,16 @@ public class SensorPrivacyTile extends QSTileImpl<BooleanState> implements ResourceIcon.get(R.drawable.ic_signal_sensors); private final KeyguardMonitor mKeyguard; private final SensorPrivacyManager mSensorPrivacyManager; + private final ActivityStarter mActivityStarter; - public SensorPrivacyTile(QSHost host) { + @Inject + public SensorPrivacyTile(QSHost host, SensorPrivacyManager sensorPrivacyManager, + KeyguardMonitor keyguardMonitor, ActivityStarter activityStarter) { super(host); - mSensorPrivacyManager = Dependency.get(SensorPrivacyManager.class); - mKeyguard = Dependency.get(KeyguardMonitor.class); + mSensorPrivacyManager = sensorPrivacyManager; + mKeyguard = keyguardMonitor; + mActivityStarter = activityStarter; } @Override @@ -57,7 +62,7 @@ public class SensorPrivacyTile extends QSTileImpl<BooleanState> implements final boolean wasEnabled = mState.value; // Don't allow disabling from the lockscreen. if (wasEnabled && mKeyguard.isSecure() && mKeyguard.isShowing()) { - Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> { + mActivityStarter.postQSRunnableDismissingKeyguard(() -> { MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled); setEnabled(!wasEnabled); }); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java index e5c51a66fafa..7c1ffde8f00a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java @@ -22,7 +22,6 @@ import android.provider.Settings; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; @@ -31,16 +30,21 @@ import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserSwitcherController; +import javax.inject.Inject; + public class UserTile extends QSTileImpl<State> implements UserInfoController.OnUserInfoChangedListener { private final UserSwitcherController mUserSwitcherController; private final UserInfoController mUserInfoController; private Pair<String, Drawable> mLastUpdate; - public UserTile(QSHost host) { + @Inject + public UserTile(QSHost host, UserSwitcherController userSwitcherController, + UserInfoController userInfoController) { super(host); - mUserSwitcherController = Dependency.get(UserSwitcherController.class); - mUserInfoController = Dependency.get(UserInfoController.class); + mUserSwitcherController = userSwitcherController; + mUserInfoController = userInfoController; + mUserInfoController.observe(getLifecycle(), this); } @Override @@ -70,11 +74,6 @@ public class UserTile extends QSTileImpl<State> implements UserInfoController.On @Override public void handleSetListening(boolean listening) { - if (listening) { - mUserInfoController.addCallback(this); - } else { - mUserInfoController.removeCallback(this); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 6939ae7039f2..52a88145c7ed 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -30,7 +30,6 @@ import android.widget.Switch; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.wifi.AccessPoint; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; @@ -51,6 +50,8 @@ import com.android.systemui.statusbar.policy.WifiIcons; import java.util.List; +import javax.inject.Inject; + /** Quick settings tile: Wifi **/ public class WifiTile extends QSTileImpl<SignalState> { private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS); @@ -64,12 +65,15 @@ public class WifiTile extends QSTileImpl<SignalState> { private final ActivityStarter mActivityStarter; private boolean mExpectDisabled; - public WifiTile(QSHost host) { + @Inject + public WifiTile(QSHost host, NetworkController networkController, + ActivityStarter activityStarter) { super(host); - mController = Dependency.get(NetworkController.class); + mController = networkController; mWifiController = mController.getAccessPointController(); mDetailAdapter = (WifiDetailAdapter) createDetailAdapter(); - mActivityStarter = Dependency.get(ActivityStarter.class); + mActivityStarter = activityStarter; + mController.observe(getLifecycle(), mSignalCallback); } @Override @@ -79,11 +83,6 @@ public class WifiTile extends QSTileImpl<SignalState> { @Override public void handleSetListening(boolean listening) { - if (listening) { - mController.addCallback(mSignalCallback); - } else { - mController.removeCallback(mSignalCallback); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java index 3109deaf7239..f921eb9a49a6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -22,13 +22,14 @@ import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; import com.android.systemui.R; 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.phone.ManagedProfileController; +import javax.inject.Inject; + /** Quick settings tile: Work profile on/off */ public class WorkModeTile extends QSTileImpl<BooleanState> implements ManagedProfileController.Callback { @@ -36,9 +37,11 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements private final ManagedProfileController mProfileController; - public WorkModeTile(QSHost host) { + @Inject + public WorkModeTile(QSHost host, ManagedProfileController managedProfileController) { super(host); - mProfileController = Dependency.get(ManagedProfileController.class); + mProfileController = managedProfileController; + mProfileController.observe(getLifecycle(), this); } @Override @@ -48,11 +51,6 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements @Override public void handleSetListening(boolean listening) { - if (listening) { - mProfileController.addCallback(this); - } else { - mProfileController.removeCallback(this); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 12b6f673de1c..81757d0aadd4 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -44,7 +44,6 @@ import android.util.Log; import android.view.MotionEvent; import com.android.internal.policy.ScreenDecorationsUtils; -import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.Prefs; import com.android.systemui.SysUiServiceProvider; @@ -63,9 +62,13 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Class to send information from overview to launcher with a binder. */ +@Singleton public class OverviewProxyService implements CallbackController<OverviewProxyListener>, Dumpable { private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE"; @@ -86,8 +89,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final Handler mHandler; private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser; private final ComponentName mRecentsComponentName; - private final DeviceProvisionedController mDeviceProvisionedController - = Dependency.get(DeviceProvisionedController.class); + private final DeviceProvisionedController mDeviceProvisionedController; private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>(); private final Intent mQuickStepIntent; @@ -338,9 +340,11 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final IBinder.DeathRecipient mOverviewServiceDeathRcpt = this::cleanupAfterDeath; - public OverviewProxyService(Context context) { + @Inject + public OverviewProxyService(Context context, DeviceProvisionedController provisionController) { mContext = context; mHandler = new Handler(); + mDeviceProvisionedController = provisionController; mConnectionBackoffAttempts = 0; mRecentsComponentName = ComponentName.unflattenFromString(context.getString( com.android.internal.R.string.config_recentsComponentName)); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java deleted file mode 100644 index 2f2610998b35..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java +++ /dev/null @@ -1,139 +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.statusbar; - -import static android.view.Display.DEFAULT_DISPLAY; - -import android.content.Context; -import android.hardware.display.DisplayManager; -import android.hardware.display.DisplayManager.DisplayListener; -import android.os.Handler; -import android.os.RemoteException; -import android.util.Log; -import android.util.SparseArray; -import android.view.Display; -import android.view.IWindowManager; -import android.view.View; -import android.view.WindowManagerGlobal; - -import com.android.systemui.statusbar.phone.NavigationBarFragment; - -/** - * A controller to handle external navigation bars - */ -public class DisplayNavigationBarController implements DisplayListener { - - private static final String TAG = DisplayNavigationBarController.class.getName(); - - private final Context mContext; - private final Handler mHandler; - private final DisplayManager mDisplayManager; - - /** A displayId - nav bar mapping */ - private SparseArray<NavigationBarFragment> mExternalNavigationBarMap = new SparseArray<>(); - - public DisplayNavigationBarController(Context context, Handler handler) { - mContext = context; - mHandler = handler; - mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); - - registerListener(); - } - - @Override - public void onDisplayAdded(int displayId) { - final Display display = mDisplayManager.getDisplay(displayId); - addExternalNavigationBar(display); - } - - @Override - public void onDisplayRemoved(int displayId) { - final NavigationBarFragment navBar = mExternalNavigationBarMap.get(displayId); - if (navBar != null) { - final View navigationView = navBar.getView().getRootView(); - WindowManagerGlobal.getInstance().removeView(navigationView, true); - mExternalNavigationBarMap.remove(displayId); - } - } - - @Override - public void onDisplayChanged(int displayId) { - } - - /** Create external navigation bars when car/status bar initializes */ - public void createNavigationBars() { - // Add external navigation bars if more than one displays exist. - final Display[] displays = mDisplayManager.getDisplays(); - for (Display display : displays) { - addExternalNavigationBar(display); - } - } - - /** remove external navigation bars and unset everything related to external navigation bars */ - public void destroy() { - unregisterListener(); - if (mExternalNavigationBarMap.size() > 0) { - for (int i = 0; i < mExternalNavigationBarMap.size(); i++) { - final View navigationWindow = mExternalNavigationBarMap.valueAt(i) - .getView().getRootView(); - WindowManagerGlobal.getInstance() - .removeView(navigationWindow, true /* immediate */); - } - mExternalNavigationBarMap.clear(); - } - } - - private void registerListener() { - mDisplayManager.registerDisplayListener(this, mHandler); - } - - private void unregisterListener() { - mDisplayManager.unregisterDisplayListener(this); - } - - /** - * Add a phone navigation bar on an external display if the display supports system decorations. - * - * @param display the display to add navigation bar on - */ - private void addExternalNavigationBar(Display display) { - if (display == null || display.getDisplayId() == DEFAULT_DISPLAY - || !display.supportsSystemDecorations()) { - return; - } - - final int displayId = display.getDisplayId(); - final IWindowManager wms = WindowManagerGlobal.getWindowManagerService(); - - try { - if (!wms.hasNavigationBar(displayId)) { - return; - } - } catch (RemoteException e) { - // Cannot get wms, just return with warning message. - Log.w(TAG, "Cannot get WindowManager."); - return; - } - final Context externalDisplayContext = mContext.createDisplayContext(display); - NavigationBarFragment.create(externalDisplayContext, (tag, fragment) -> { - final NavigationBarFragment navBar = (NavigationBarFragment) fragment; - // TODO(b/115978725): handle external nav bars sysuiVisibility - navBar.setCurrentSysuiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); - mExternalNavigationBarMap.append(displayId, navBar); - }); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java index b39a96d40828..e2177774a75d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java @@ -31,8 +31,8 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java new file mode 100644 index 000000000000..43eaff40ffe0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java @@ -0,0 +1,222 @@ +/* + * 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.statusbar; + +import static android.view.Display.DEFAULT_DISPLAY; + +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + +import android.content.Context; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; +import android.os.Handler; +import android.os.RemoteException; +import android.util.Log; +import android.util.SparseArray; +import android.view.Display; +import android.view.IWindowManager; +import android.view.View; +import android.view.WindowManagerGlobal; + +import com.android.systemui.Dependency; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; +import com.android.systemui.statusbar.phone.LightBarController; +import com.android.systemui.statusbar.phone.NavigationBarFragment; +import com.android.systemui.statusbar.phone.NavigationBarView; +import com.android.systemui.statusbar.policy.BatteryController; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + + +/** A controller to handle navigation bars. */ +@Singleton +public class NavigationBarController implements DisplayListener { + + private static final String TAG = NavigationBarController.class.getName(); + + private final Context mContext; + private final Handler mHandler; + private final DisplayManager mDisplayManager; + + /** A displayId - nav bar maps. */ + private SparseArray<NavigationBarFragment> mNavigationBars = new SparseArray<>(); + + @Inject + public NavigationBarController(Context context, @Named(MAIN_HANDLER_NAME) Handler handler) { + mContext = context; + mHandler = handler; + mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); + mDisplayManager.registerDisplayListener(this, mHandler); + } + + @Override + public void onDisplayAdded(int displayId) { + Display display = mDisplayManager.getDisplay(displayId); + createNavigationBar(display); + } + + @Override + public void onDisplayRemoved(int displayId) { + removeNavigationBar(displayId); + } + + @Override + public void onDisplayChanged(int displayId) { + } + + // TODO(b/117478341): I use {@code includeDefaultDisplay} to make this method compatible to + // CarStatusBar because they have their own nav bar. Think about a better way for it. + /** + * Creates navigation bars when car/status bar initializes. + * + * @param includeDefaultDisplay {@code true} to create navigation bar on default display. + */ + public void createNavigationBars(final boolean includeDefaultDisplay) { + Display[] displays = mDisplayManager.getDisplays(); + for (Display display : displays) { + if (includeDefaultDisplay || display.getDisplayId() != DEFAULT_DISPLAY) { + createNavigationBar(display); + } + } + } + + /** + * Adds a navigation bar on default display or an external display if the display supports + * system decorations. + * + * @param display the display to add navigation bar on. + */ + private void createNavigationBar(Display display) { + if (display == null + || (display.getDisplayId() != DEFAULT_DISPLAY + && !display.supportsSystemDecorations())) { + return; + } + + final int displayId = display.getDisplayId(); + final boolean isOnDefaultDisplay = displayId == DEFAULT_DISPLAY; + final IWindowManager wms = WindowManagerGlobal.getWindowManagerService(); + + try { + if (!wms.hasNavigationBar(displayId)) { + return; + } + } catch (RemoteException e) { + // Cannot get wms, just return with warning message. + Log.w(TAG, "Cannot get WindowManager."); + return; + } + final Context context = isOnDefaultDisplay + ? mContext + : mContext.createDisplayContext(display); + NavigationBarFragment.create(context, (tag, fragment) -> { + NavigationBarFragment navBar = (NavigationBarFragment) fragment; + + // Unfortunately, we still need it because status bar needs LightBarController + // before notifications creation. We cannot directly use getLightBarController() + // from NavigationBarFragment directly. + LightBarController controller = isOnDefaultDisplay + ? Dependency.get(LightBarController.class) + : new LightBarController(context, + Dependency.get(DarkIconDispatcher.class), + Dependency.get(BatteryController.class)); + navBar.setLightBarController(controller); + navBar.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + mNavigationBars.append(displayId, navBar); + }); + } + + /** Removes navigation bars. */ + public void destroy() { + mDisplayManager.unregisterDisplayListener(this); + if (mNavigationBars.size() > 0) { + for (int i = 0; i < mNavigationBars.size(); i++) { + int displayId = mNavigationBars.keyAt(i); + removeNavigationBar(displayId); + } + mNavigationBars.clear(); + } + } + + private void removeNavigationBar(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + View navigationWindow = navBar.getView().getRootView(); + WindowManagerGlobal.getInstance() + .removeView(navigationWindow, true /* immediate */); + mNavigationBars.remove(displayId); + } + } + + /** @see NavigationBarFragment#checkNavBarModes() */ + public void checkNavBarModes(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.checkNavBarModes(); + } + } + + /** @see NavigationBarFragment#finishBarAnimations() */ + public void finishBarAnimations(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.finishBarAnimations(); + } + } + + /** @see NavigationBarFragment#touchAutoDim() */ + public void touchAutoDim(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.touchAutoDim(); + } + } + + /** @see NavigationBarFragment#transitionTo(int, boolean) */ + public void transitionTo(int displayId, @TransitionMode int barMode, boolean animate) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.transitionTo(barMode, animate); + } + } + + /** @see NavigationBarFragment#isSemiTransparent() */ + public boolean isSemiTransparent(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + return navBar.isSemiTransparent(); + } + return false; + } + + /** @see NavigationBarFragment#disableAnimationsDuringHide(long) */ + public void disableAnimationsDuringHide(int displayId, long delay) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.disableAnimationsDuringHide(delay); + } + } + + /** @return {@link NavigationBarView} on the default display. */ + public NavigationBarView getDefaultNavigationBarView() { + NavigationBarFragment navBar = mNavigationBars.get(DEFAULT_DISPLAY); + return (navBar == null) ? null : (NavigationBarView) navBar.getView(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 7d80860fca85..1bf101c00711 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -25,11 +25,10 @@ import android.annotation.Nullable; import android.app.Notification; import android.content.Context; import android.graphics.Bitmap; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSession; @@ -38,15 +37,18 @@ import android.media.session.PlaybackState; import android.os.Handler; import android.os.Trace; import android.os.UserHandle; +import android.service.notification.StatusBarNotification; import android.util.Log; import android.view.View; import android.widget.ImageView; +import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.Interpolators; import com.android.systemui.colorextraction.SysuiColorExtractor; -import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationData.Entry; +import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.LockscreenWallpaper; @@ -64,6 +66,8 @@ import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; +import dagger.Lazy; + /** * Handles tasks and state related to media notifications. For example, there is a 'current' media * notification, which this class keeps track of. @@ -83,9 +87,9 @@ public class NotificationMediaManager implements Dumpable { // Late binding, also @Nullable due to being in com.android.systemui.statusbar.phone package @Nullable - private ShadeController mShadeController; + private Lazy<ShadeController> mShadeController; @Nullable - private StatusBarWindowController mStatusBarWindowController; + private Lazy<StatusBarWindowController> mStatusBarWindowController; @Nullable private BiometricUnlockController mBiometricUnlockController; @@ -94,14 +98,11 @@ public class NotificationMediaManager implements Dumpable { @Nullable private LockscreenWallpaper mLockscreenWallpaper; - protected final PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC); - protected final PorterDuffXfermode mSrcOverXferMode = - new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER); - private final Handler mHandler = Dependency.get(MAIN_HANDLER); private final Context mContext; private final MediaSessionManager mMediaSessionManager; + private final ArrayList<MediaListener> mMediaListeners; protected NotificationPresenter mPresenter; private MediaController mMediaController; @@ -122,7 +123,7 @@ public class NotificationMediaManager implements Dumpable { if (state != null) { if (!isPlaybackActive(state.getState())) { clearCurrentMediaNotification(); - mPresenter.updateMediaMetaData(true, true); + dispatchUpdateMediaMetaData(true /* changed */, true /* allowAnimation */); } } } @@ -134,40 +135,39 @@ public class NotificationMediaManager implements Dumpable { Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata); } mMediaMetadata = metadata; - mPresenter.updateMediaMetaData(true, true); + dispatchUpdateMediaMetaData(true /* changed */, true /* allowAnimation */); } }; - @Nullable - private ShadeController getShadeController() { - if (mShadeController == null) { - mShadeController = Dependency.get(ShadeController.class); - } - return mShadeController; - } - - @Nullable - private StatusBarWindowController getWindowController() { - if (mStatusBarWindowController == null) { - mStatusBarWindowController = Dependency.get(StatusBarWindowController.class); - } - return mStatusBarWindowController; - } - - private NotificationEntryManager getEntryManager() { - if (mEntryManager == null) { - mEntryManager = Dependency.get(NotificationEntryManager.class); - } - return mEntryManager; - } - @Inject - public NotificationMediaManager(Context context) { + public NotificationMediaManager( + Context context, + Lazy<ShadeController> shadeController, + Lazy<StatusBarWindowController> statusBarWindowController, + NotificationEntryManager notificationEntryManager) { mContext = context; + mMediaListeners = new ArrayList<>(); mMediaSessionManager = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE); // TODO: use MediaSessionManager.SessionListener to hook us up to future updates // in session state + mShadeController = shadeController; + mStatusBarWindowController = statusBarWindowController; + mEntryManager = notificationEntryManager; + notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { + @Override + public void onEntryRemoved( + @Nullable Entry entry, + String key, + StatusBarNotification old, + NotificationVisibility visibility, + boolean lifetimeExtended, + boolean removedByUser) { + if (!lifetimeExtended) { + onNotificationRemoved(key); + } + } + }); } public void setUpWithPresenter(NotificationPresenter presenter) { @@ -177,7 +177,7 @@ public class NotificationMediaManager implements Dumpable { public void onNotificationRemoved(String key) { if (key.equals(mMediaNotificationKey)) { clearCurrentMediaNotification(); - mPresenter.updateMediaMetaData(true, true); + dispatchUpdateMediaMetaData(true /* changed */, true /* allowEnterAnimation */); } } @@ -189,20 +189,42 @@ public class NotificationMediaManager implements Dumpable { return mMediaMetadata; } + public Icon getMediaIcon() { + if (mMediaNotificationKey == null) { + return null; + } + synchronized (mEntryManager.getNotificationData()) { + Entry entry = mEntryManager.getNotificationData().get(mMediaNotificationKey); + if (entry == null || entry.expandedIcon == null) { + return null; + } + + return entry.expandedIcon.getSourceIcon(); + } + } + + public void addCallback(MediaListener callback) { + mMediaListeners.add(callback); + callback.onMetadataChanged(mMediaMetadata); + } + + public void removeCallback(MediaListener callback) { + mMediaListeners.remove(callback); + } + public void findAndUpdateMediaNotifications() { boolean metaDataChanged = false; - NotificationEntryManager manager = getEntryManager(); - synchronized (manager.getNotificationData()) { - ArrayList<NotificationData.Entry> activeNotifications = manager - .getNotificationData().getActiveNotifications(); + synchronized (mEntryManager.getNotificationData()) { + ArrayList<Entry> activeNotifications = + mEntryManager.getNotificationData().getActiveNotifications(); final int N = activeNotifications.size(); // Promote the media notification with a controller in 'playing' state, if any. - NotificationData.Entry mediaNotification = null; + Entry mediaNotification = null; MediaController controller = null; for (int i = 0; i < N; i++) { - final NotificationData.Entry entry = activeNotifications.get(i); + final Entry entry = activeNotifications.get(i); if (entry.isMediaNotification()) { final MediaSession.Token token = @@ -242,7 +264,7 @@ public class NotificationMediaManager implements Dumpable { final String pkg = aController.getPackageName(); for (int i = 0; i < N; i++) { - final NotificationData.Entry entry = activeNotifications.get(i); + final Entry entry = activeNotifications.get(i); if (entry.notification.getPackageName().equals(pkg)) { if (DEBUG_MEDIA) { Log.v(TAG, "DEBUG_MEDIA: found controller matching " @@ -283,12 +305,10 @@ public class NotificationMediaManager implements Dumpable { } if (metaDataChanged) { - getEntryManager().updateNotifications(); + mEntryManager.updateNotifications(); } - if (mPresenter != null) { - mPresenter.updateMediaMetaData(metaDataChanged, true); - } + dispatchUpdateMediaMetaData(metaDataChanged, true /* allowEnterAnimation */); } public void clearCurrentMediaNotification() { @@ -296,6 +316,16 @@ public class NotificationMediaManager implements Dumpable { clearCurrentMediaNotificationSession(); } + private void dispatchUpdateMediaMetaData(boolean changed, boolean allowEnterAnimation) { + if (mPresenter != null) { + mPresenter.updateMediaMetaData(changed, allowEnterAnimation); + } + ArrayList<MediaListener> callbacks = new ArrayList<>(mMediaListeners); + for (int i = 0; i < callbacks.size(); i++) { + callbacks.get(i).onMetadataChanged(mMediaMetadata); + } + } + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.print(" mMediaSessionManager="); @@ -410,8 +440,9 @@ public class NotificationMediaManager implements Dumpable { } } - boolean hideBecauseOccluded = getShadeController() != null - && getShadeController().isOccluded(); + ShadeController shadeController = mShadeController.get(); + StatusBarWindowController windowController = mStatusBarWindowController.get(); + boolean hideBecauseOccluded = shadeController != null && shadeController.isOccluded(); final boolean hasArtwork = artworkDrawable != null; mColorExtractor.setHasBackdrop(hasArtwork); @@ -434,8 +465,8 @@ public class NotificationMediaManager implements Dumpable { mBackdrop.animate().cancel(); mBackdrop.setAlpha(1f); } - if (getWindowController() != null) { - getWindowController().setBackdropShowing(true); + if (windowController != null) { + windowController.setBackdropShowing(true); } metaDataChanged = true; if (DEBUG_MEDIA) { @@ -482,8 +513,8 @@ public class NotificationMediaManager implements Dumpable { if (DEBUG_MEDIA) { Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork"); } - boolean cannotAnimateDoze = getShadeController() != null - && getShadeController().isDozing() + boolean cannotAnimateDoze = shadeController != null + && shadeController.isDozing() && !ScrimState.AOD.getAnimateChange(); if (mBiometricUnlockController != null && mBiometricUnlockController.getMode() == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING @@ -492,12 +523,12 @@ public class NotificationMediaManager implements Dumpable { // We are unlocking directly - no animation! mBackdrop.setVisibility(View.GONE); mBackdropBack.setImageDrawable(null); - if (getWindowController() != null) { - getWindowController().setBackdropShowing(false); + if (windowController != null) { + windowController.setBackdropShowing(false); } } else { - if (getWindowController() != null) { - getWindowController().setBackdropShowing(false); + if (windowController != null) { + windowController.setBackdropShowing(false); } mBackdrop.animate() .alpha(0) @@ -552,4 +583,8 @@ public class NotificationMediaManager implements Dumpable { mBackdropFront.setImageDrawable(null); } }; + + public interface MediaListener { + void onMetadataChanged(MediaMetadata metadata); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index d1556fb33f92..886d99eeff17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -17,7 +17,10 @@ package com.android.systemui.statusbar; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.KeyguardManager; @@ -26,6 +29,7 @@ import android.app.PendingIntent; import android.app.RemoteInput; import android.content.Context; import android.content.Intent; +import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; @@ -46,9 +50,9 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; -import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.phone.ShadeController; @@ -60,8 +64,11 @@ import java.util.ArrayList; import java.util.Set; import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; +import dagger.Lazy; + /** * Class for handling remote input state over a set of notifications. This class handles things * like keeping notifications temporarily that were cancelled as a response to a remote input @@ -100,15 +107,12 @@ public class NotificationRemoteInputManager implements Dumpable { new ArraySet<>(); // Dependencies: - protected final NotificationLockscreenUserManager mLockscreenUserManager = - Dependency.get(NotificationLockscreenUserManager.class); - protected final SmartReplyController mSmartReplyController = - Dependency.get(SmartReplyController.class); - private final NotificationEntryManager mEntryManager - = Dependency.get(NotificationEntryManager.class); + private final NotificationLockscreenUserManager mLockscreenUserManager; + private final SmartReplyController mSmartReplyController; + private final NotificationEntryManager mEntryManager; + private final Handler mMainHandler; - // Lazy - private ShadeController mShadeController; + private final Lazy<ShadeController> mShadeController; protected final Context mContext; private final UserManager mUserManager; @@ -126,7 +130,7 @@ public class NotificationRemoteInputManager implements Dumpable { @Override public boolean onClickHandler( View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) { - getShadeController().wakeUpIfDozing(SystemClock.uptimeMillis(), view); + mShadeController.get().wakeUpIfDozing(SystemClock.uptimeMillis(), view); if (handleRemoteInput(view, pendingIntent)) { return true; @@ -226,21 +230,40 @@ public class NotificationRemoteInputManager implements Dumpable { } }; - private ShadeController getShadeController() { - if (mShadeController == null) { - mShadeController = Dependency.get(ShadeController.class); - } - return mShadeController; - } - @Inject - public NotificationRemoteInputManager(Context context) { + public NotificationRemoteInputManager( + Context context, + NotificationLockscreenUserManager lockscreenUserManager, + SmartReplyController smartReplyController, + NotificationEntryManager notificationEntryManager, + Lazy<ShadeController> shadeController, + @Named(MAIN_HANDLER_NAME) Handler mainHandler) { mContext = context; + mLockscreenUserManager = lockscreenUserManager; + mSmartReplyController = smartReplyController; + mEntryManager = notificationEntryManager; + mShadeController = shadeController; + mMainHandler = mainHandler; mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); addLifetimeExtenders(); mKeyguardManager = context.getSystemService(KeyguardManager.class); + + notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { + @Override + public void onEntryRemoved( + @Nullable NotificationData.Entry entry, + String key, + StatusBarNotification old, + NotificationVisibility visibility, + boolean lifetimeExtended, + boolean removedByUser) { + if (removedByUser && entry != null) { + onPerformRemoveNotification(entry, key); + } + } + }); } /** Initializes this component with the provided dependencies. */ @@ -258,7 +281,7 @@ public class NotificationRemoteInputManager implements Dumpable { // view it is already canceled, so we'll need to cancel it on the apps behalf // after sending - unless the app posts an update in the mean time, so wait a // bit. - Dependency.get(Dependency.MAIN_HANDLER).postDelayed(() -> { + mMainHandler.postDelayed(() -> { if (mEntriesKeptForRemoteInputActive.remove(entry)) { mNotificationLifetimeFinishedCallback.onSafeToRemove(entry.key); } @@ -392,10 +415,10 @@ public class NotificationRemoteInputManager implements Dumpable { return mRemoteInputController; } - public void onPerformRemoveNotification(StatusBarNotification n, - NotificationData.Entry entry) { - if (mKeysKeptForRemoteInputHistory.contains(n.getKey())) { - mKeysKeptForRemoteInputHistory.remove(n.getKey()); + @VisibleForTesting + void onPerformRemoveNotification(NotificationData.Entry entry, final String key) { + if (mKeysKeptForRemoteInputHistory.contains(key)) { + mKeysKeptForRemoteInputHistory.remove(key); } if (mRemoteInputController.isRemoteInputActive(entry)) { mRemoteInputController.removeRemoteInput(entry, null); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index 017cda741e5f..017a9c368fdf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -25,7 +25,6 @@ import android.util.Log; import android.view.View; import android.view.ViewGroup; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.statusbar.notification.NotificationData; @@ -44,6 +43,8 @@ import java.util.Stack; import javax.inject.Inject; import javax.inject.Singleton; +import dagger.Lazy; + /** * NotificationViewHierarchyManager manages updating the view hierarchy of notification views based * on their group structure. For example, if a notification becomes bundled with another, @@ -60,20 +61,15 @@ public class NotificationViewHierarchyManager { mTmpChildOrderMap = new HashMap<>(); // Dependencies: - protected final NotificationLockscreenUserManager mLockscreenUserManager = - Dependency.get(NotificationLockscreenUserManager.class); - protected final NotificationGroupManager mGroupManager = - Dependency.get(NotificationGroupManager.class); - protected final VisualStabilityManager mVisualStabilityManager = - Dependency.get(VisualStabilityManager.class); - private final StatusBarStateController mStatusBarStateController = - Dependency.get(StatusBarStateController.class); - private final NotificationEntryManager mEntryManager = - Dependency.get(NotificationEntryManager.class); - private final BubbleController mBubbleController = Dependency.get(BubbleController.class); + protected final NotificationLockscreenUserManager mLockscreenUserManager; + protected final NotificationGroupManager mGroupManager; + protected final VisualStabilityManager mVisualStabilityManager; + private final StatusBarStateController mStatusBarStateController; + private final NotificationEntryManager mEntryManager; + private final BubbleController mBubbleController; // Lazy - private ShadeController mShadeController; + private final Lazy<ShadeController> mShadeController; /** * {@code true} if notifications not part of a group should by default be rendered in their @@ -120,20 +116,27 @@ public class NotificationViewHierarchyManager { } } - private ShadeController getShadeController() { - if (mShadeController == null) { - mShadeController = Dependency.get(ShadeController.class); - } - return mShadeController; - } - @Inject - public NotificationViewHierarchyManager(Context context) { + public NotificationViewHierarchyManager(Context context, + NotificationLockscreenUserManager notificationLockscreenUserManager, + NotificationGroupManager groupManager, + VisualStabilityManager visualStabilityManager, + StatusBarStateController statusBarStateController, + NotificationEntryManager notificationEntryManager, + BubbleController bubbleController, + Lazy<ShadeController> shadeController) { + mLockscreenUserManager = notificationLockscreenUserManager; + mGroupManager = groupManager; + mVisualStabilityManager = visualStabilityManager; + mStatusBarStateController = statusBarStateController; + mEntryManager = notificationEntryManager; + mBubbleController = bubbleController; + mShadeController = shadeController; Resources res = context.getResources(); mAlwaysExpandNonGroupedNotification = res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications); mStatusBarStateListener = new StatusBarStateListener(mBubbleController); - Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener); + mStatusBarStateController.addCallback(mStatusBarStateListener); } public void setUpWithPresenter(NotificationPresenter presenter, @@ -396,7 +399,7 @@ public class NotificationViewHierarchyManager { && !row.isLowPriority())); } - entry.getRow().setOnAmbient(getShadeController().isDozing()); + entry.getRow().setOnAmbient(mShadeController.get().isDozing()); int userId = entry.notification.getUserId(); boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup( entry.notification) && !entry.isRowRemoved(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java index f1a891b95eaa..d1b3c3cb12d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java @@ -30,8 +30,8 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.WirelessUtils; import com.android.systemui.DemoMode; import com.android.systemui.Dependency; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index e7b768f30023..6d2c001dc153 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -41,9 +41,9 @@ import android.widget.LinearLayout; import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarIconController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.IconLogger; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java index 6f1548d2fb5f..9e91133aff09 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java @@ -21,7 +21,6 @@ import android.util.ArraySet; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; -import com.android.systemui.Dependency; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; @@ -36,15 +35,16 @@ import javax.inject.Singleton; */ @Singleton public class SmartReplyController { - private IStatusBarService mBarService; + private final IStatusBarService mBarService; + private final NotificationEntryManager mEntryManager; private Set<String> mSendingKeys = new ArraySet<>(); private Callback mCallback; - private final NotificationEntryManager mEntryManager = - Dependency.get(NotificationEntryManager.class); @Inject - public SmartReplyController() { - mBarService = Dependency.get(IStatusBarService.class); + public SmartReplyController(NotificationEntryManager entryManager, + IStatusBarService statusBarService) { + mBarService = statusBarService; + mEntryManager = entryManager; } public void setCallback(Callback callback) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 8b61a5bccc3c..3c1335456d04 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -16,7 +16,7 @@ package com.android.systemui.statusbar; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index bc89889c48fe..4db981d2dcd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -16,11 +16,11 @@ package com.android.systemui.statusbar; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea; import android.content.Context; import android.content.res.ColorStateList; @@ -37,8 +37,8 @@ import android.widget.LinearLayout; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; public class StatusBarMobileView extends FrameLayout implements DarkReceiver, StatusIconDisplayable { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java index 045221f510fa..c5751c300c01 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java @@ -16,11 +16,11 @@ package com.android.systemui.statusbar; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea; import android.content.Context; import android.content.res.ColorStateList; @@ -37,8 +37,8 @@ import android.widget.LinearLayout; import com.android.settingslib.Utils; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; /** * Start small: StatusBarWifiView will be able to layout from a WifiIconState diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java index beb90b893ec8..d541fae4ed33 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java @@ -16,7 +16,7 @@ package com.android.systemui.statusbar; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; public interface StatusIconDisplayable extends DarkReceiver { String getSlot(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java index 6560f8f9c420..442416fd3bea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java @@ -26,6 +26,12 @@ import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class VibratorHelper { private final Vibrator mVibrator; @@ -44,6 +50,9 @@ public class VibratorHelper { } }; + /** + */ + @Inject public VibratorHelper(Context context) { mContext = context; mVibrator = context.getSystemService(Vibrator.class); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java new file mode 100644 index 000000000000..7b42dd901d72 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java @@ -0,0 +1,189 @@ +/* + * 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.statusbar.notification; + +import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY; +import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT; +import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP; + +import android.annotation.Nullable; +import android.app.Notification; +import android.service.notification.StatusBarNotification; +import android.util.Log; + +import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.statusbar.AlertingNotificationManager; +import com.android.systemui.statusbar.AmbientPulseManager; +import com.android.systemui.statusbar.NotificationListener; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.notification.row.NotificationInflater; +import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.policy.HeadsUpManager; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import dagger.Lazy; + +/** Handles heads-up and pulsing behavior driven by notification changes. */ +@Singleton +public class NotificationAlertingManager { + + private static final String TAG = "NotifAlertManager"; + + private final AmbientPulseManager mAmbientPulseManager; + private final NotificationRemoteInputManager mRemoteInputManager; + private final VisualStabilityManager mVisualStabilityManager; + private final Lazy<ShadeController> mShadeController; + private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider; + private final NotificationListener mNotificationListener; + + private HeadsUpManager mHeadsUpManager; + + @Inject + public NotificationAlertingManager( + NotificationEntryManager notificationEntryManager, + AmbientPulseManager ambientPulseManager, + NotificationRemoteInputManager remoteInputManager, + VisualStabilityManager visualStabilityManager, + Lazy<ShadeController> shadeController, + NotificationInterruptionStateProvider notificationInterruptionStateProvider, + NotificationListener notificationListener) { + mAmbientPulseManager = ambientPulseManager; + mRemoteInputManager = remoteInputManager; + mVisualStabilityManager = visualStabilityManager; + mShadeController = shadeController; + mNotificationInterruptionStateProvider = notificationInterruptionStateProvider; + mNotificationListener = notificationListener; + + notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { + @Override + public void onEntryInflated(NotificationData.Entry entry, int inflatedFlags) { + showAlertingView(entry, inflatedFlags); + } + + @Override + public void onEntryUpdated(NotificationData.Entry entry) { + updateAlertState(entry); + } + + @Override + public void onEntryRemoved( + @Nullable NotificationData.Entry entry, + String key, + StatusBarNotification old, + NotificationVisibility visibility, + boolean lifetimeExtended, + boolean removedByUser) { + stopAlerting(key); + } + }); + } + + public void setHeadsUpManager(HeadsUpManager headsUpManager) { + mHeadsUpManager = headsUpManager; + } + + /** + * Adds the entry to the respective alerting manager if the content view was inflated and + * the entry should still alert. + * + * @param entry entry to add + * @param inflatedFlags flags representing content views that were inflated + */ + private void showAlertingView(NotificationData.Entry entry, + @NotificationInflater.InflationFlag int inflatedFlags) { + if ((inflatedFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) { + // Possible for shouldHeadsUp to change between the inflation starting and ending. + // If it does and we no longer need to heads up, we should free the view. + if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) { + mHeadsUpManager.showNotification(entry); + // Mark as seen immediately + setNotificationShown(entry.notification); + } else { + entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP); + } + } + if ((inflatedFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) { + if (mNotificationInterruptionStateProvider.shouldPulse(entry)) { + mAmbientPulseManager.showNotification(entry); + } else { + entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT); + } + } + } + + private void updateAlertState(NotificationData.Entry entry) { + boolean alertAgain = alertAgain(entry, entry.notification.getNotification()); + AlertingNotificationManager alertManager; + boolean shouldAlert; + if (mShadeController.get().isDozing()) { + alertManager = mAmbientPulseManager; + shouldAlert = mNotificationInterruptionStateProvider.shouldPulse(entry); + } else { + alertManager = mHeadsUpManager; + shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry); + } + final boolean wasAlerting = alertManager.isAlerting(entry.key); + if (wasAlerting) { + if (!shouldAlert) { + // We don't want this to be interrupting anymore, let's remove it + alertManager.removeNotification(entry.key, + false /* ignoreEarliestRemovalTime */); + } else { + alertManager.updateNotification(entry.key, alertAgain); + } + } else if (shouldAlert && alertAgain) { + // This notification was updated to be alerting, show it! + alertManager.showNotification(entry); + } + } + + private static boolean alertAgain( + NotificationData.Entry oldEntry, Notification newNotification) { + return oldEntry == null || !oldEntry.hasInterrupted() + || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0; + } + + private void setNotificationShown(StatusBarNotification n) { + try { + mNotificationListener.setNotificationsShown(new String[]{n.getKey()}); + } catch (RuntimeException e) { + Log.d(TAG, "failed setNotificationsShown: ", e); + } + } + + private void stopAlerting(final String key) { + // Attempt to remove notifications from their alert managers (heads up, ambient pulse). + // Though the remove itself may fail, it lets the manager know to remove as soon as + // possible. + if (mHeadsUpManager.isAlerting(key)) { + // A cancel() in response to a remote input shouldn't be delayed, as it makes the + // sending look longer than it takes. + // Also we should not defer the removal if reordering isn't allowed since otherwise + // some notifications can't disappear before the panel is closed. + boolean ignoreEarliestRemovalTime = + mRemoteInputManager.getController().isSpinning(key) + && !FORCE_REMOTE_INPUT_HISTORY + || !mVisualStabilityManager.isReorderingAllowed(); + mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime); + } + if (mAmbientPulseManager.isAlerting(key)) { + mAmbientPulseManager.removeNotification(key, false /* ignoreEarliestRemovalTime */); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java index 433a994ac0cc..a51896ee69fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java @@ -90,7 +90,7 @@ public class NotificationData { private static final long INITIALIZATION_DELAY = 400; private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN; private static final int COLOR_INVALID = 1; - public String key; + public final String key; public StatusBarNotification notification; public NotificationChannel channel; public long lastAudiblyAlertedMs; @@ -827,6 +827,14 @@ public class NotificationData { return removed; } + /** Updates the given notification entry with the provided ranking. */ + public void update(Entry entry, RankingMap ranking, StatusBarNotification notification) { + updateRanking(ranking); + final StatusBarNotification oldNotification = entry.notification; + entry.notification = notification; + mGroupManager.onEntryUpdated(entry, oldNotification); + } + public void updateRanking(RankingMap ranking) { updateRankingAndSort(ranking); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java index 361ae8b1920a..1d06ce031f2b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java @@ -15,8 +15,12 @@ */ package com.android.systemui.statusbar.notification; +import android.annotation.Nullable; import android.service.notification.StatusBarNotification; +import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.statusbar.notification.row.NotificationInflater; + /** * Listener interface for changes sent by NotificationEntryManager. */ @@ -37,39 +41,50 @@ public interface NotificationEntryListener { /** * Called when a notification was updated. */ - default void onNotificationUpdated(StatusBarNotification notification) { + default void onEntryUpdated(NotificationData.Entry entry) { } /** - * Called when an existing notification's views are reinflated (usually due to an update being - * posted to that notification). + * Called when a notification's views are inflated for the first time. */ - default void onEntryReinflated(NotificationData.Entry entry) { + default void onEntryInflated(NotificationData.Entry entry, + @NotificationInflater.InflationFlag int inflatedFlags) { } /** - * Called when a notification has been removed (either because the user swiped it away or - * because the developer retracted it). + * Called when an existing notification's views are reinflated (usually due to an update being + * posted to that notification). * - * TODO: combine this with onNotificationRemoved(). + * @param entry notification data entry that was reinflated. */ - default void onEntryRemoved(NotificationData.Entry entry) { + default void onEntryReinflated(NotificationData.Entry entry) { } /** - * Called when a notification was removed. - * - * @param key key of notification that was removed - * @param old StatusBarNotification of the notification before it was removed + * Called when an error occurred inflating the views for a notification. */ - default void onNotificationRemoved(String key, StatusBarNotification old) { + default void onInflationError(StatusBarNotification notification, Exception exception) { } /** - * Removes a notification immediately. - * - * TODO: combine this with onNotificationRemoved(). + * Called when a notification has been removed (either because the user swiped it away or + * because the developer retracted it). + * @param entry notification data entry that was removed. Null if no entry existed for the + * removed key at the time of removal. + * @param key key of notification that was removed + * @param old StatusBarNotification of the notification before it was removed + * @param visibility logging data related to the visibility of the notification at the time of + * removal, if it was removed by a user action. Null if it was not removed by + * a user action. + * @param lifetimeExtended true if something is artificially extending how long the notification + * @param removedByUser true if the notification was removed by a user action */ - default void onPerformRemoveNotification(StatusBarNotification statusBarNotification) { + default void onEntryRemoved( + @Nullable NotificationData.Entry entry, + String key, + StatusBarNotification old, + @Nullable NotificationVisibility visibility, + boolean lifetimeExtended, + boolean removedByUser) { } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index 98ddd6b9cc5c..e0fa723730c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -16,37 +16,26 @@ package com.android.systemui.statusbar.notification; import static com.android.systemui.bubbles.BubbleController.DEBUG_DEMOTE_TO_NOTIF; -import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY; -import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT; -import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP; import android.annotation.Nullable; import android.app.Notification; import android.content.Context; import android.os.Handler; import android.os.PowerManager; -import android.os.RemoteException; -import android.os.ServiceManager; import android.os.UserHandle; import android.service.notification.NotificationListenerService; -import android.service.notification.NotificationStats; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.ForegroundServiceController; import com.android.systemui.bubbles.BubbleController; -import com.android.systemui.statusbar.AlertingNotificationManager; -import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.NotificationLifetimeExtender; -import com.android.systemui.statusbar.NotificationListener; -import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationUiAdjustment; @@ -57,8 +46,6 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationInflater; import com.android.systemui.statusbar.notification.row.NotificationInflater.InflationFlag; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; -import com.android.systemui.statusbar.phone.NotificationGroupManager; -import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.leak.LeakDetector; @@ -89,35 +76,22 @@ public class NotificationEntryManager implements protected final Context mContext; protected final HashMap<String, NotificationData.Entry> mPendingNotifications = new HashMap<>(); - private final NotificationGroupManager mGroupManager = - Dependency.get(NotificationGroupManager.class); private final NotificationGutsManager mGutsManager = Dependency.get(NotificationGutsManager.class); private final DeviceProvisionedController mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - private final VisualStabilityManager mVisualStabilityManager = - Dependency.get(VisualStabilityManager.class); private final ForegroundServiceController mForegroundServiceController = Dependency.get(ForegroundServiceController.class); - private final AmbientPulseManager mAmbientPulseManager = - Dependency.get(AmbientPulseManager.class); private final BubbleController mBubbleController = Dependency.get(BubbleController.class); - private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider = - Dependency.get(NotificationInterruptionStateProvider.class); // Lazily retrieved dependencies private NotificationRemoteInputManager mRemoteInputManager; - private NotificationMediaManager mMediaManager; - private NotificationListener mNotificationListener; - private ShadeController mShadeController; private NotificationRowBinder mNotificationRowBinder; private final Handler mDeferredNotificationViewUpdateHandler; private Runnable mUpdateNotificationViewsCallback; - protected IStatusBarService mBarService; private NotificationPresenter mPresenter; - private NotificationEntryListener mCallback; protected PowerManager mPowerManager; private NotificationListenerService.RankingMap mLatestRankingMap; protected HeadsUpManager mHeadsUpManager; @@ -157,8 +131,6 @@ public class NotificationEntryManager implements public NotificationEntryManager(Context context) { mContext = context; mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mBarService = IStatusBarService.Stub.asInterface( - ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mBubbleController.setDismissListener(this /* bubbleEventListener */); mNotificationData = new NotificationData(); mDeferredNotificationViewUpdateHandler = new Handler(); @@ -179,27 +151,6 @@ public class NotificationEntryManager implements return mRemoteInputManager; } - private NotificationMediaManager getMediaManager() { - if (mMediaManager == null) { - mMediaManager = Dependency.get(NotificationMediaManager.class); - } - return mMediaManager; - } - - private NotificationListener getNotificationListener() { - if (mNotificationListener == null) { - mNotificationListener = Dependency.get(NotificationListener.class); - } - return mNotificationListener; - } - - private ShadeController getShadeController() { - if (mShadeController == null) { - mShadeController = Dependency.get(ShadeController.class); - } - return mShadeController; - } - private NotificationRowBinder getRowBinder() { if (mNotificationRowBinder == null) { mNotificationRowBinder = Dependency.get(NotificationRowBinder.class); @@ -208,25 +159,28 @@ public class NotificationEntryManager implements } public void setUpWithPresenter(NotificationPresenter presenter, - NotificationListContainer listContainer, NotificationEntryListener callback, + NotificationListContainer listContainer, HeadsUpManager headsUpManager) { mPresenter = presenter; mUpdateNotificationViewsCallback = mPresenter::updateNotificationViews; - mCallback = callback; mHeadsUpManager = headsUpManager; mNotificationData.setHeadsUpManager(mHeadsUpManager); mListContainer = listContainer; - mNotificationLifetimeExtenders.add(mHeadsUpManager); - mNotificationLifetimeExtenders.add(mAmbientPulseManager); - mNotificationLifetimeExtenders.add(mGutsManager); - mNotificationLifetimeExtenders.addAll(getRemoteInputManager().getLifetimeExtenders()); + mDeviceProvisionedController.addCallback(mDeviceProvisionedListener); + } - for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) { - extender.setCallback(key -> removeNotification(key, mLatestRankingMap)); + /** Adds multiple {@link NotificationLifetimeExtender}s. */ + public void addNotificationLifetimeExtenders(List<NotificationLifetimeExtender> extenders) { + for (NotificationLifetimeExtender extender : extenders) { + addNotificationLifetimeExtender(extender); } + } - mDeviceProvisionedController.addCallback(mDeviceProvisionedListener); + /** Adds a {@link NotificationLifetimeExtender}. */ + public void addNotificationLifetimeExtender(NotificationLifetimeExtender extender) { + mNotificationLifetimeExtenders.add(extender); + extender.setCallback(key -> removeNotification(key, mLatestRankingMap)); } public NotificationData getNotificationData() { @@ -255,30 +209,8 @@ public class NotificationEntryManager implements final int count = mNotificationData.getActiveNotifications().size(); final NotificationVisibility nv = NotificationVisibility.obtain(n.getKey(), rank, count, true); - NotificationData.Entry entry = mNotificationData.get(n.getKey()); - - getRemoteInputManager().onPerformRemoveNotification(n, entry); - final String pkg = n.getPackageName(); - final String tag = n.getTag(); - final int id = n.getId(); - final int userId = n.getUserId(); - try { - int dismissalSurface = NotificationStats.DISMISSAL_SHADE; - if (mHeadsUpManager.isAlerting(n.getKey())) { - dismissalSurface = NotificationStats.DISMISSAL_PEEK; - } else if (mListContainer.hasPulsingNotifications()) { - dismissalSurface = NotificationStats.DISMISSAL_AOD; - } - int dismissalSentiment = NotificationStats.DISMISS_SENTIMENT_NEUTRAL; - mBarService.onNotificationClear(pkg, tag, id, userId, n.getKey(), dismissalSurface, - dismissalSentiment, nv); - removeNotification(n.getKey(), null); - - } catch (RemoteException ex) { - // system process is dead if we're here. - } - - mCallback.onPerformRemoveNotification(n); + removeNotificationInternal( + n.getKey(), null, nv, false /* forceRemove */, true /* removedByUser */); } @Override @@ -318,12 +250,10 @@ public class NotificationEntryManager implements */ @Override public void handleInflationException(StatusBarNotification n, Exception e) { - removeNotificationInternal(n.getKey(), null, true /* forceRemove */); - try { - mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(), - n.getInitialPid(), e.getMessage(), n.getUserId()); - } catch (RemoteException ex) { - // The end is nigh. + removeNotificationInternal( + n.getKey(), null, null, true /* forceRemove */, false /* removedByUser */); + for (NotificationEntryListener listener : mNotificationEntryListeners) { + listener.onInflationError(n, e); } } @@ -335,7 +265,9 @@ public class NotificationEntryManager implements mNotificationData.add(shadeEntry); tagForeground(shadeEntry.notification); updateNotifications(); - mCallback.onNotificationAdded(shadeEntry); + for (NotificationEntryListener listener : mNotificationEntryListeners) { + listener.onNotificationAdded(shadeEntry); + } maybeScheduleUpdateNotificationViews(shadeEntry); } @@ -349,35 +281,6 @@ public class NotificationEntryManager implements } } - /** - * Adds the entry to the respective alerting manager if the content view was inflated and - * the entry should still alert. - * - * @param entry entry to add - * @param inflatedFlags flags representing content views that were inflated - */ - private void showAlertingView(NotificationData.Entry entry, - @InflationFlag int inflatedFlags) { - if ((inflatedFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) { - // Possible for shouldHeadsUp to change between the inflation starting and ending. - // If it does and we no longer need to heads up, we should free the view. - if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) { - mHeadsUpManager.showNotification(entry); - // Mark as seen immediately - setNotificationShown(entry.notification); - } else { - entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP); - } - } - if ((inflatedFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) { - if (mNotificationInterruptionStateProvider.shouldPulse(entry)) { - mAmbientPulseManager.showNotification(entry); - } else { - entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT); - } - } - } - @Override public void onAsyncInflationFinished(NotificationData.Entry entry, @InflationFlag int inflatedFlags) { @@ -387,13 +290,11 @@ public class NotificationEntryManager implements if (!entry.isRowRemoved()) { boolean isNew = mNotificationData.get(entry.key) == null; if (isNew) { - showAlertingView(entry, inflatedFlags); + for (NotificationEntryListener listener : mNotificationEntryListeners) { + listener.onEntryInflated(entry, inflatedFlags); + } addEntry(entry); } else { - if (entry.getRow().hasLowPriorityStateUpdated()) { - mVisualStabilityManager.onLowPriorityUpdated(entry); - mPresenter.updateNotificationViews(); - } for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onEntryReinflated(entry); } @@ -404,75 +305,62 @@ public class NotificationEntryManager implements @Override public void removeNotification(String key, NotificationListenerService.RankingMap ranking) { - removeNotificationInternal(key, ranking, false /* forceRemove */); + removeNotificationInternal( + key, ranking, null, false /* forceRemove */, false /* removedByUser */); } - private void removeNotificationInternal(String key, - @Nullable NotificationListenerService.RankingMap ranking, boolean forceRemove) { + private void removeNotificationInternal( + String key, + @Nullable NotificationListenerService.RankingMap ranking, + @Nullable NotificationVisibility visibility, + boolean forceRemove, + boolean removedByUser) { final NotificationData.Entry entry = mNotificationData.get(key); abortExistingInflation(key); - if (entry != null) { - for (NotificationEntryListener listener : mNotificationEntryListeners) { - listener.onEntryRemoved(entry); - } - } - - // Attempt to remove notifications from their alert managers (heads up, ambient pulse). - // Though the remove itself may fail, it lets the manager know to remove as soon as - // possible. - if (mHeadsUpManager.isAlerting(key)) { - // A cancel() in response to a remote input shouldn't be delayed, as it makes the - // sending look longer than it takes. - // Also we should not defer the removal if reordering isn't allowed since otherwise - // some notifications can't disappear before the panel is closed. - boolean ignoreEarliestRemovalTime = getRemoteInputManager().getController().isSpinning(key) - && !FORCE_REMOTE_INPUT_HISTORY - || !mVisualStabilityManager.isReorderingAllowed(); - mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime); - } - if (mAmbientPulseManager.isAlerting(key)) { - mAmbientPulseManager.removeNotification(key, false /* ignoreEarliestRemovalTime */); - } - if (entry == null) { - mCallback.onNotificationRemoved(key, null /* old */); - return; - } + StatusBarNotification old = null; + boolean lifetimeExtended = false; - // If a manager needs to keep the notification around for whatever reason, we return early - // and keep the notification - if (!forceRemove) { - for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) { - if (extender.shouldExtendLifetime(entry)) { - mLatestRankingMap = ranking; - extender.setShouldManageLifetime(entry, true /* shouldManage */); - return; + if (entry != null) { + // If a manager needs to keep the notification around for whatever reason, we + // keep the notification + if (!forceRemove) { + for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) { + if (extender.shouldExtendLifetime(entry)) { + mLatestRankingMap = ranking; + extender.setShouldManageLifetime(entry, true /* shouldManage */); + lifetimeExtended = true; + break; + } } } - } - // At this point, we are guaranteed the notification will be removed + if (!lifetimeExtended) { + // At this point, we are guaranteed the notification will be removed - // Ensure any managers keeping the lifetime extended stop managing the entry - for (NotificationLifetimeExtender extender: mNotificationLifetimeExtenders) { - extender.setShouldManageLifetime(entry, false /* shouldManage */); - } + // Ensure any managers keeping the lifetime extended stop managing the entry + for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) { + extender.setShouldManageLifetime(entry, false /* shouldManage */); + } - getMediaManager().onNotificationRemoved(key); - mForegroundServiceController.removeNotification(entry.notification); + mForegroundServiceController.removeNotification(entry.notification); - if (entry.rowExists()) { - entry.removeRow(); - mListContainer.cleanUpViewStateForEntry(entry); - } + if (entry.rowExists()) { + entry.removeRow(); + mListContainer.cleanUpViewStateForEntry(entry); + } - // Let's remove the children if this was a summary - handleGroupSummaryRemoved(key); + // Let's remove the children if this was a summary + handleGroupSummaryRemoved(key); - StatusBarNotification old = removeNotificationViews(key, ranking); + old = removeNotificationViews(key, ranking); + } + } - mCallback.onNotificationRemoved(key, old); + for (NotificationEntryListener listener : mNotificationEntryListeners) { + listener.onEntryRemoved(entry, key, old, visibility, lifetimeExtended, removedByUser); + } } private StatusBarNotification removeNotificationViews(String key, @@ -616,11 +504,6 @@ public class NotificationEntryManager implements } } - private boolean alertAgain(NotificationData.Entry oldEntry, Notification newNotification) { - return oldEntry == null || !oldEntry.hasInterrupted() - || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0; - } - private void updateNotificationInternal(StatusBarNotification notification, NotificationListenerService.RankingMap ranking) throws InflationException { if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")"); @@ -638,11 +521,7 @@ public class NotificationEntryManager implements extender.setShouldManageLifetime(entry, false /* shouldManage */); } - mNotificationData.updateRanking(ranking); - - final StatusBarNotification oldNotification = entry.notification; - entry.notification = notification; - mGroupManager.onEntryUpdated(entry, oldNotification); + mNotificationData.update(entry, ranking, notification); entry.updateIcons(mContext, notification); getRowBinder().inflateViews(entry, () -> performRemoveNotification(notification), @@ -651,14 +530,6 @@ public class NotificationEntryManager implements mForegroundServiceController.updateNotification(notification, mNotificationData.getImportance(key)); - boolean alertAgain = alertAgain(entry, entry.notification.getNotification()); - if (getShadeController().isDozing()) { - updateAlertState(entry, mNotificationInterruptionStateProvider.shouldPulse(entry), - alertAgain, mAmbientPulseManager); - } else { - updateAlertState(entry, mNotificationInterruptionStateProvider.shouldHeadsUp(entry), - alertAgain, mHeadsUpManager); - } updateNotifications(); if (!notification.isClearable()) { @@ -674,7 +545,9 @@ public class NotificationEntryManager implements Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you"); } - mCallback.onNotificationUpdated(notification); + for (NotificationEntryListener listener : mNotificationEntryListeners) { + listener.onEntryUpdated(entry); + } maybeScheduleUpdateNotificationViews(entry); } @@ -739,43 +612,6 @@ public class NotificationEntryManager implements } } - private void setNotificationShown(StatusBarNotification n) { - setNotificationsShown(new String[]{n.getKey()}); - } - - protected void setNotificationsShown(String[] keys) { - try { - getNotificationListener().setNotificationsShown(keys); - } catch (RuntimeException e) { - Log.d(TAG, "failed setNotificationsShown: ", e); - } - } - - /** - * Update the entry's alert state and call the appropriate {@link AlertingNotificationManager} - * method. - * @param entry entry to update - * @param shouldAlert whether or not it should be alerting - * @param alertAgain whether or not an alert should actually come in as if it were new - * @param alertManager the alerting notification manager that manages the alert state - */ - private void updateAlertState(NotificationData.Entry entry, boolean shouldAlert, - boolean alertAgain, AlertingNotificationManager alertManager) { - final boolean wasAlerting = alertManager.isAlerting(entry.key); - if (wasAlerting) { - if (!shouldAlert) { - // We don't want this to be interrupting anymore, lets remove it - alertManager.removeNotification(entry.key, - false /* ignoreEarliestRemovalTime */); - } else { - alertManager.updateNotification(entry.key, alertAgain); - } - } else if (shouldAlert && alertAgain) { - // This notification was updated to be alerting, show it! - alertManager.showNotification(entry); - } - } - /** * @return An iterator for all "pending" notifications. Pending notifications are newly-posted * notifications whose views have not yet been inflated. In general, the system pretends like diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java index abb7b4161984..8e6a93deec69 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java @@ -20,6 +20,7 @@ import android.view.View; import androidx.collection.ArraySet; +import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; @@ -37,6 +38,7 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener { private final ArrayList<Callback> mCallbacks = new ArrayList<>(); + private NotificationPresenter mPresenter; private boolean mPanelExpanded; private boolean mScreenOn; private boolean mReorderingAllowed; @@ -47,7 +49,22 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener { private boolean mPulsing; @Inject - public VisualStabilityManager() { + public VisualStabilityManager(NotificationEntryManager notificationEntryManager) { + notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { + @Override + public void onEntryReinflated(NotificationData.Entry entry) { + if (entry.hasLowPriorityStateUpdated()) { + onLowPriorityUpdated(entry); + if (mPresenter != null) { + mPresenter.updateNotificationViews(); + } + } + } + }); + } + + public void setUpWithPresenter(NotificationPresenter presenter) { + mPresenter = presenter; } /** @@ -154,7 +171,7 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener { } } - public void onLowPriorityUpdated(NotificationData.Entry entry) { + private void onLowPriorityUpdated(NotificationData.Entry entry) { mLowPriorityReorderingViews.add(entry.getRow()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java index eb1fc30843b3..32acb8df173c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java @@ -15,26 +15,30 @@ */ package com.android.systemui.statusbar.notification.logging; +import android.annotation.Nullable; import android.content.Context; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.service.notification.NotificationListenerService; +import android.service.notification.NotificationStats; +import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; -import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; +import com.android.systemui.statusbar.policy.HeadsUpManager; import java.util.ArrayList; import java.util.Collection; @@ -59,11 +63,10 @@ public class NotificationLogger implements StateListener { new ArraySet<>(); // Dependencies: - private final NotificationListenerService mNotificationListener = - Dependency.get(NotificationListener.class); - private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); - protected NotificationEntryManager mEntryManager - = Dependency.get(NotificationEntryManager.class); + private final NotificationListenerService mNotificationListener; + private final UiOffloadThread mUiOffloadThread; + private final NotificationEntryManager mEntryManager; + private HeadsUpManager mHeadsUpManager; protected Handler mHandler = new Handler(); protected IStatusBarService mBarService; @@ -150,17 +153,49 @@ public class NotificationLogger implements StateListener { }; @Inject - public NotificationLogger() { + public NotificationLogger(NotificationListener notificationListener, + UiOffloadThread uiOffloadThread, + NotificationEntryManager entryManager, + StatusBarStateController statusBarStateController) { + mNotificationListener = notificationListener; + mUiOffloadThread = uiOffloadThread; + mEntryManager = entryManager; mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); // Not expected to be destroyed, don't need to unsubscribe - Dependency.get(StatusBarStateController.class).addCallback(this); + statusBarStateController.addCallback(this); + + entryManager.addNotificationEntryListener(new NotificationEntryListener() { + @Override + public void onEntryRemoved( + @Nullable NotificationData.Entry entry, + String key, + StatusBarNotification old, + NotificationVisibility visibility, + boolean lifetimeExtended, + boolean removedByUser) { + if (removedByUser && visibility != null && entry.notification != null) { + logNotificationClear(key, entry.notification, visibility); + } + } + + @Override + public void onInflationError( + StatusBarNotification notification, + Exception exception) { + logNotificationError(notification, exception); + } + }); } public void setUpWithContainer(NotificationListContainer listContainer) { mListContainer = listContainer; } + public void setHeadsUpManager(HeadsUpManager headsUpManager) { + mHeadsUpManager = headsUpManager; + } + public void stopNotificationLogging() { // Report all notifications as invisible and turn down the // reporter. @@ -190,6 +225,45 @@ public class NotificationLogger implements StateListener { } } + private void logNotificationClear(String key, StatusBarNotification notification, + NotificationVisibility nv) { + final String pkg = notification.getPackageName(); + final String tag = notification.getTag(); + final int id = notification.getId(); + final int userId = notification.getUserId(); + try { + int dismissalSurface = NotificationStats.DISMISSAL_SHADE; + if (mHeadsUpManager.isAlerting(key)) { + dismissalSurface = NotificationStats.DISMISSAL_PEEK; + } else if (mListContainer.hasPulsingNotifications()) { + dismissalSurface = NotificationStats.DISMISSAL_AOD; + } + int dismissalSentiment = NotificationStats.DISMISS_SENTIMENT_NEUTRAL; + mBarService.onNotificationClear(pkg, tag, id, userId, notification.getKey(), + dismissalSurface, + dismissalSentiment, nv); + } catch (RemoteException ex) { + // system process is dead if we're here. + } + } + + private void logNotificationError( + StatusBarNotification notification, + Exception exception) { + try { + mBarService.onNotificationError( + notification.getPackageName(), + notification.getTag(), + notification.getId(), + notification.getUid(), + notification.getInitialPid(), + exception.getMessage(), + notification.getUserId()); + } catch (RemoteException ex) { + // The end is nigh. + } + } + private void logNotificationVisibilityChanges( Collection<NotificationVisibility> newlyVisible, Collection<NotificationVisibility> noLongerVisible) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java index 5329541db92a..b1eab8069307 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java @@ -40,6 +40,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; +import android.metrics.LogMaker; import android.os.Handler; import android.os.RemoteException; import android.service.notification.StatusBarNotification; @@ -150,6 +151,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G // Reset exit counter that we'll log and record an undo event separately (not an exit event) mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED; logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO); + mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS)); swapContent(ACTION_UNDO, true /* animate */); }; @@ -381,6 +383,17 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G } } + /** + * Returns an initialized LogMaker for logging importance changes. + * The caller may override the type (to DISMISS) before passing it to mMetricsLogger. + * @return new LogMaker + */ + private LogMaker importanceChangeLogMaker() { + return new LogMaker(MetricsEvent.ACTION_SAVE_IMPORTANCE) + .setType(MetricsEvent.TYPE_ACTION) + .setSubtype(mChosenImportance - mStartingChannelImportance); + } + private boolean hasImportanceChanged() { return mSingleNotificationChannel != null && mStartingChannelImportance != mChosenImportance; @@ -397,8 +410,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G * Commits the updated importance values on the background thread. */ private void updateImportance() { - MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE, - mChosenImportance - mStartingChannelImportance); + mMetricsLogger.write(importanceChangeLogMaker()); Handler bgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER)); bgHandler.post(new UpdateImportanceRunnable(mINotificationManager, mPackageName, mAppUid, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java index 8c8bad2ab196..a5411ecb4bd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java @@ -87,8 +87,8 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso try { drawable = mResolver.resolveImage(target); - } catch (IOException ex) { - Log.d(TAG, "PreloadImageTask: Resolve failed from " + target); + } catch (IOException | SecurityException ex) { + Log.d(TAG, "PreloadImageTask: Resolve failed from " + target, ex); } return drawable; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java index 588246f3d2c6..a3e13053d169 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java @@ -81,8 +81,8 @@ public class NotificationInlineImageResolver implements ImageResolver { Drawable result = null; try { result = hasCache() ? mImageCache.get(uri) : resolveImage(uri); - } catch (IOException ex) { - Log.d(TAG, "loadImage: Can't load image from " + uri); + } catch (IOException | SecurityException ex) { + Log.d(TAG, "loadImage: Can't load image from " + uri, ex); } return result; } 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 67a5cd934a6b..f982ecf6f103 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 @@ -5823,7 +5823,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd (int) (dragLengthY / mDisplayMetrics.density), 0 /* velocityDp - N/A */); - if (mNotificationPanel.onDraggedDown() || startingChild != null) { + if (!mAmbientState.isDark() || startingChild != null) { // We have notifications, go to locked shade. mShadeController.goToLockedShade(startingChild); if (startingChild instanceof ExpandableNotificationRow) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java index 3d814732a2e7..79056175b595 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import android.annotation.IntDef; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; @@ -36,6 +37,9 @@ import com.android.settingslib.Utils; import com.android.systemui.Interpolators; import com.android.systemui.R; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + public class BarTransitions { private static final boolean DEBUG = false; private static final boolean DEBUG_COLORS = false; @@ -48,6 +52,18 @@ public class BarTransitions { public static final int MODE_WARNING = 5; public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6; + @IntDef(flag = true, prefix = { "MODE_" }, value = { + MODE_OPAQUE, + MODE_SEMI_TRANSPARENT, + MODE_TRANSLUCENT, + MODE_LIGHTS_OUT, + MODE_TRANSPARENT, + MODE_WARNING, + MODE_LIGHTS_OUT_TRANSPARENT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface TransitionMode {} + public static final int LIGHTS_IN_DURATION = 250; public static final int LIGHTS_OUT_DURATION = 1500; public static final int BACKGROUND_DURATION = 200; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java index 5906dc29fa08..08a10dc925e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java @@ -14,7 +14,8 @@ package com.android.systemui.statusbar.phone; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.DEFAULT_ICON_TINT; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; import android.animation.ArgbEvaluator; import android.content.Context; @@ -24,12 +25,18 @@ import android.util.ArrayMap; import android.widget.ImageView; import com.android.systemui.R; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import java.io.FileDescriptor; import java.io.PrintWriter; -public class DarkIconDispatcherImpl implements DarkIconDispatcher { +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton +public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher { private final LightBarTransitionsController mTransitionsController; private final Rect mTintArea = new Rect(); @@ -40,6 +47,9 @@ public class DarkIconDispatcherImpl implements DarkIconDispatcher { private int mDarkModeIconColorSingleTone; private int mLightModeIconColorSingleTone; + /** + */ + @Inject public DarkIconDispatcherImpl(Context context) { mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone); mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 3425dd237430..236c72c5cc2c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -29,14 +29,14 @@ import android.widget.LinearLayout; import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.DemoMode; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarMobileView; import com.android.systemui.statusbar.StatusBarWifiView; import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 92a9efe743d0..6f2b63d2e64d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -158,8 +158,11 @@ public class DozeParameters implements TunerService.Tunable { * @return duration in millis. */ public long getWallpaperAodDuration() { - return shouldControlScreenOff() ? DozeScreenState.ENTER_DOZE_HIDE_WALLPAPER_DELAY - : mAlwaysOnPolicy.wallpaperVisibilityDuration; + if (mAmbientDisplayConfiguration.wakeLockScreenGestureEnabled(UserHandle.USER_CURRENT) + || shouldControlScreenOff()) { + return DozeScreenState.ENTER_DOZE_HIDE_WALLPAPER_DELAY; + } + return mAlwaysOnPolicy.wallpaperVisibilityDuration; } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java index cfa751cec613..280dda0cd1dc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java @@ -65,10 +65,11 @@ public class DozeScrimController implements StateListener { if (!mDozing) { return; } - // All pulses except notifications should time out on their own. Pulses due to - // notifications should instead be managed externally based off the notification's - // lifetime. - if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION) { + // Notifications should time out on their own. Pulses due to notifications should + // instead be managed externally based off the notification's lifetime. + // Dock also controls the time out by self. + if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION + && mPulseReason != DozeLog.PULSE_REASON_DOCKING) { mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration()); mHandler.postDelayed(mPulseOutExtended, mDozeParameters.getPulseVisibleDurationExtended()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index 3c8cad7cb60b..d1e488ab2b4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -25,12 +25,12 @@ import android.view.WindowInsets; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.HeadsUpStatusBarView; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import java.util.function.BiConsumer; 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 21c506b68319..2e9d9bcda61e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.phone; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; -import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON; import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK; import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON; @@ -54,7 +53,6 @@ import android.telecom.TelecomManager; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; -import android.util.MathUtils; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; @@ -172,8 +170,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private boolean mDozing; private int mIndicationBottomMargin; private float mDarkAmount; - private int mBurnInXOffset; - private int mBurnInYOffset; public KeyguardBottomAreaView(Context context) { this(context, null); @@ -250,8 +246,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mIndicationText = findViewById(R.id.keyguard_indication_text); mIndicationBottomMargin = getResources().getDimensionPixelSize( R.dimen.keyguard_indication_margin_bottom); - mBurnInYOffset = getResources().getDimensionPixelSize( - R.dimen.default_burn_in_prevention_offset); updateCameraVisibility(); mUnlockMethodCache = UnlockMethodCache.getInstance(getContext()); mUnlockMethodCache.addListener(this); @@ -322,8 +316,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL super.onConfigurationChanged(newConfig); mIndicationBottomMargin = getResources().getDimensionPixelSize( R.dimen.keyguard_indication_margin_bottom); - mBurnInYOffset = getResources().getDimensionPixelSize( - R.dimen.default_burn_in_prevention_offset); MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams(); if (mlp.bottomMargin != mIndicationBottomMargin) { mlp.bottomMargin = mIndicationBottomMargin; @@ -569,7 +561,15 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mDarkAmount = darkAmount; mIndicationController.setDarkAmount(darkAmount); mLockIcon.setDarkAmount(darkAmount); - dozeTimeTick(); + } + + /** + * When keyguard is in pulsing (AOD2) state. + * @param pulsing {@code true} when pulsing. + * @param animated if transition should be animated. + */ + public void setPulsing(boolean pulsing, boolean animated) { + mLockIcon.setPulsing(pulsing, animated); } private static boolean isSuccessfulLaunch(int result) { @@ -830,6 +830,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL updateCameraVisibility(); updateLeftAffordanceIcon(); + mLockIcon.setDozing(dozing); if (dozing) { mOverlayContainer.setVisibility(INVISIBLE); @@ -841,21 +842,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } } - public void dozeTimeTick() { - // Move views every minute to avoid burn-in - int burnInYOffset = -getBurnInOffset(mBurnInYOffset, false /* xAxis */); - burnInYOffset = (int) MathUtils.lerp(0, burnInYOffset, mDarkAmount); - mLockIcon.setTranslationY(burnInYOffset); - } - - public void setBurnInXOffset(int burnInXOffset) { - if (mBurnInXOffset == burnInXOffset) { - return; - } - mBurnInXOffset = burnInXOffset; - mLockIcon.setTranslationX(burnInXOffset); - } - private class DefaultLeftButton implements IntentButton { private IconState mIconState = new IconState(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java index b3423a84542e..927228eae20e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java @@ -22,7 +22,6 @@ import android.util.Log; import com.android.systemui.Dependency; import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -34,8 +33,6 @@ public class KeyguardEnvironmentImpl implements KeyguardEnvironment { Dependency.get(NotificationLockscreenUserManager.class); private final DeviceProvisionedController mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - private final NotificationMediaManager mMediaManager = - Dependency.get(NotificationMediaManager.class); public KeyguardEnvironmentImpl() { } 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 5ba59b507fec..03375d20e6db 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -45,13 +45,13 @@ import com.android.systemui.BatteryMeterView; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.qs.QSPanel; import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java index 7c30e48f171a..b590ca7f4df0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java @@ -25,23 +25,26 @@ import android.graphics.Rect; import android.view.View; import com.android.internal.colorextraction.ColorExtractor.GradientColors; -import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.policy.BatteryController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import java.io.FileDescriptor; import java.io.PrintWriter; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Controls how light status bar flag applies to the icons. */ +@Singleton public class LightBarController implements BatteryController.BatteryStateChangeCallback, Dumpable { private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f; - private final DarkIconDispatcher mStatusBarIconController; + private final SysuiDarkIconDispatcher mStatusBarIconController; private final BatteryController mBatteryController; private BiometricUnlockController mBiometricUnlockController; @@ -76,14 +79,13 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private final Rect mLastDockedBounds = new Rect(); private boolean mQsCustomizing; - private final Context mContext; - - public LightBarController(Context ctx) { + @Inject + public LightBarController(Context ctx, DarkIconDispatcher darkIconDispatcher, + BatteryController batteryController) { mDarkModeColor = Color.valueOf(ctx.getColor(R.color.dark_mode_icon_color_single_tone)); - mStatusBarIconController = Dependency.get(DarkIconDispatcher.class); - mBatteryController = Dependency.get(BatteryController.class); + mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher; + mBatteryController = batteryController; mBatteryController.addCallback(this); - mContext = ctx; } public void setNavigationBar(LightBarTransitionsController navigationBar) { @@ -220,9 +222,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private void updateNavigation() { if (mNavigationBarController != null) { - if (!NavBarTintController.isEnabled(mContext)) { - mNavigationBarController.setIconsDark(mNavigationLight, animateChange()); - } + mNavigationBarController.setIconsDark( + mNavigationLight, animateChange()); } } @@ -263,10 +264,6 @@ public class LightBarController implements BatteryController.BatteryStateChangeC pw.println(); - if (mStatusBarIconController != null) { - mStatusBarIconController.dump(fd, pw, args); - } - LightBarTransitionsController transitionsController = mStatusBarIconController.getTransitionsController(); if (transitionsController != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java index 1be39750d561..d934d952c4c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -45,8 +45,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private static final int STATE_FACE_UNLOCK = 2; private static final int STATE_FINGERPRINT = 3; private static final int STATE_FINGERPRINT_ERROR = 4; - private static final boolean HOLLOW_PILL = SystemProperties - .getBoolean("persist.sysui.hollow_pill", false); private int mLastState = 0; private boolean mLastDeviceInteractive; @@ -60,6 +58,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private boolean mHasFingerPrintIcon; private boolean mHasFaceUnlockIcon; private int mDensity; + private boolean mPulsing; + private boolean mDozing; private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */); private float mDarkAmount; @@ -159,6 +159,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange mLastScreenOn = mScreenOn; } + setVisibility(mDozing && !mPulsing ? GONE : VISIBLE); updateClickability(); } @@ -224,16 +225,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange throw new IllegalArgumentException(); } - if (HOLLOW_PILL && deviceInteractive) { - switch (state) { - case STATE_FINGERPRINT: - case STATE_LOCK_OPEN: - case STATE_LOCKED: - case STATE_FACE_UNLOCK: - iconRes = R.drawable.ic_home_button_outline; - } - } - return mContext.getDrawable(iconRes); } @@ -281,6 +272,24 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange updateDarkTint(); } + /** + * When keyguard is in pulsing (AOD2) state. + * @param pulsing {@code true} when pulsing. + * @param animated if transition should be animated. + */ + public void setPulsing(boolean pulsing, boolean animated) { + mPulsing = pulsing; + update(); + } + + /** + * Sets the dozing state of the keyguard. + */ + public void setDozing(boolean dozing) { + mDozing = dozing; + update(); + } + private void updateDarkTint() { Drawable drawable = getDrawable().mutate(); int color = ColorUtils.blendARGB(Color.TRANSPARENT, Color.WHITE, mDarkAmount); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java index 7621887b4170..12819535cfb6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java @@ -25,16 +25,21 @@ import com.android.systemui.Dependency; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Wrapper that emits both new- and old-style gesture logs. * TODO: delete this once the old logs are no longer needed. */ +@Singleton public class LockscreenGestureLogger { private ArrayMap<Integer, Integer> mLegacyMap; private LogMaker mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN) .setType(MetricsEvent.TYPE_ACTION); private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); + @Inject public LockscreenGestureLogger() { mLegacyMap = new ArrayMap<>(EventLogConstants.METRICS_GESTURE_TYPE_MAP.length); for (int i = 0; i < EventLogConstants.METRICS_GESTURE_TYPE_MAP.length ; i++) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java index 0f8d59b12ddb..fbd8d8a76d26 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java @@ -28,6 +28,12 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class ManagedProfileControllerImpl implements ManagedProfileController { private final List<Callback> mCallbacks = new ArrayList<>(); @@ -38,6 +44,9 @@ public class ManagedProfileControllerImpl implements ManagedProfileController { private boolean mListening; private int mCurrentUser; + /** + */ + @Inject public ManagedProfileControllerImpl(Context context) { mContext = context; mUserManager = UserManager.get(mContext); 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 2daff2cb18bc..270565be8bab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -16,14 +16,19 @@ package com.android.systemui.statusbar.phone; import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT; import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN; +import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.windowStateToString; import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; +import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE; import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions; @@ -55,6 +60,7 @@ import android.telecom.TelecomManager; import android.text.TextUtils; import android.util.Log; import android.view.Display; +import android.view.IWindowManager; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -63,6 +69,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; +import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; @@ -72,6 +79,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.AssistManager; @@ -83,6 +91,8 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.ContextualButton.ContextButtonListener; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; @@ -111,6 +121,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback /** Allow some time inbetween the long press for back and recents. */ private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; + private static final long AUTOHIDE_TIMEOUT_MS = 2250; private final AccessibilityManagerWrapper mAccessibilityManagerWrapper; protected final AssistManager mAssistManager; @@ -122,10 +133,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback private int mNavigationBarWindowState = WINDOW_STATE_SHOWING; private int mNavigationIconHints = 0; - private int mNavigationBarMode; + private @TransitionMode int mNavigationBarMode; private AccessibilityManager mAccessibilityManager; private MagnificationContentObserver mMagnificationObserver; private ContentResolver mContentResolver; + private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); private int mDisabledFlags1; private int mDisabledFlags2; @@ -144,9 +156,15 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback private OverviewProxyService mOverviewProxyService; - private boolean mIsOnDefaultDisplay = true; + private int mDisplayId; + private boolean mIsOnDefaultDisplay; public boolean mHomeBlockedThisTouch; + private Handler mHandler = Dependency.get(Dependency.MAIN_HANDLER); + + // last value sent to window manager + private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE; + private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { @Override public void onConnectionChanged(boolean isConnected) { @@ -183,14 +201,20 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } }; - private final ContextButtonListener mRotationButtonListener = new ContextButtonListener() { - @Override - public void onVisibilityChanged(ContextualButton button, boolean visible) { - if (visible) { - // If the button will actually become visible and the navbar is about to hide, - // tell the statusbar to keep it around for longer - mStatusBar.touchAutoHide(); - } + private final ContextButtonListener mRotationButtonListener = (button, visible) -> { + if (visible) { + // If the button will actually become visible and the navbar is about to hide, + // tell the statusbar to keep it around for longer + touchAutoHide(); + } + }; + + private final Runnable mAutoDim = () -> getBarTransitions().setAutoDim(true); + + private final Runnable mAutoHide = () -> { + int requested = mSystemUiVisibility & ~View.NAVIGATION_BAR_TRANSIENT; + if (mSystemUiVisibility != requested) { + notifySystemUiVisibilityChanged(requested); } }; @@ -251,7 +275,8 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback final Display display = view.getDisplay(); // It may not have display when running unit test. if (display != null) { - mIsOnDefaultDisplay = display.getDisplayId() == Display.DEFAULT_DISPLAY; + mDisplayId = display.getDisplayId(); + mIsOnDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; } mNavigationBarView.setComponents(mStatusBar.getPanel()); @@ -381,7 +406,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback if (mNavigationBarView != null) { mNavigationBarView.setNavigationIconHints(hints); } - mStatusBar.checkBarModes(); + checkBarModes(); } @Override @@ -426,23 +451,22 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback .onRotationProposal(rotation, winRotation, isValid); } - // Injected from StatusBar at creation. - public void setCurrentSysuiVisibility(int systemUiVisibility) { + /** + * Sets System UI flags to {@link NavigationBarFragment}. + * + * @see View#setSystemUiVisibility(int) + */ + public void setSystemUiVisibility(int systemUiVisibility) { mSystemUiVisibility = systemUiVisibility; - final int barMode = mStatusBar.computeBarMode(0, mSystemUiVisibility, - View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT, - View.NAVIGATION_BAR_TRANSPARENT); + final int barMode = computeBarMode(0, mSystemUiVisibility); if (barMode != -1) { mNavigationBarMode = barMode; } checkNavBarModes(); - mStatusBar.touchAutoHide(); + touchAutoHide(); - // TODO(115978725): Support light bar controller on external nav bars. - if (mLightBarController != null) { - mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */, + mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */, true /* nbModeChanged */, mNavigationBarMode); - } } @Override @@ -457,9 +481,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback // update navigation bar mode final int nbMode = getView() == null - ? -1 : mStatusBar.computeBarMode(oldVal, newVal, - View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT, - View.NAVIGATION_BAR_TRANSPARENT); + ? -1 : computeBarMode(oldVal, newVal); nbModeChanged = nbMode != -1; if (nbModeChanged) { if (mNavigationBarMode != nbMode) { @@ -470,14 +492,46 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mNavigationBarMode = nbMode; checkNavBarModes(); } - mStatusBar.touchAutoHide(); + touchAutoHide(); + } + if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) { + mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE; + } + + + // On the default display, just make StatusBar do this job. + if (!mIsOnDefaultDisplay) { + notifySystemUiVisibilityChanged(mSystemUiVisibility); } } + mLightBarController.onNavigationVisibilityChanged( + vis, mask, nbModeChanged, mNavigationBarMode); + } - // TODO(115978725): Support light bar controller on external nav bars. - if (mLightBarController != null) { - mLightBarController.onNavigationVisibilityChanged(vis, mask, nbModeChanged, - mNavigationBarMode); + private @TransitionMode int computeBarMode(int oldVis, int newVis) { + final int oldMode = barMode(oldVis); + final int newMode = barMode(newVis); + if (oldMode == newMode) { + return -1; // no mode change + } + return newMode; + } + + private @TransitionMode int barMode(int vis) { + final int lightsOutTransparent = + View.SYSTEM_UI_FLAG_LOW_PROFILE | View.NAVIGATION_BAR_TRANSIENT; + if ((vis & View.NAVIGATION_BAR_TRANSIENT) != 0) { + return MODE_SEMI_TRANSPARENT; + } else if ((vis & View.NAVIGATION_BAR_TRANSLUCENT) != 0) { + return MODE_TRANSLUCENT; + } else if ((vis & lightsOutTransparent) == lightsOutTransparent) { + return MODE_LIGHTS_OUT_TRANSPARENT; + } else if ((vis & View.NAVIGATION_BAR_TRANSPARENT) != 0) { + return MODE_TRANSPARENT; + } else if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { + return MODE_LIGHTS_OUT; + } else { + return MODE_OPAQUE; } } @@ -511,7 +565,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } } - // ----- Internal stuffz ----- + // ----- Internal stuff ----- private void refreshLayout(int layoutDirection) { if (mNavigationBarView != null) { @@ -610,7 +664,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } private boolean onNavigationTouch(View v, MotionEvent event) { - mStatusBar.checkUserAutohide(event); + checkUserAutoHide(event); return false; } @@ -800,7 +854,79 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mNavigationBarView.setAccessibilityButtonState(showAccessibilityButton, targetSelection); } - // ----- Methods that StatusBar talks to (should be minimized) ----- + private void touchAutoHide() { + // There is status bar on default display. Thus the hide animations should apply on both + // status/navigation bar. + if (mIsOnDefaultDisplay) { + mStatusBar.touchAutoHide(); + } else { + touchAutoHideInternal(); + } + } + + private void touchAutoHideInternal() { + // update transient bar autoHide. + if (isSemiTransparent()) { + scheduleAutoHide(); + } else { + cancelAutoHide(); + } + } + + private void checkUserAutoHide(MotionEvent event) { + // There is status bar on default display. Thus the hide animations should apply on both + // status/navigation bar. + if (mIsOnDefaultDisplay) { + mStatusBar.checkUserAutoHide(event); + } else { + checkUserAutoHideInternal(event); + } + } + + private void checkUserAutoHideInternal(MotionEvent event) { + if ((mSystemUiVisibility & View.NAVIGATION_BAR_TRANSIENT) != 0 + // a transient bar is revealed + && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar. + && event.getX() == 0 && event.getY() == 0) { // a touch outside both bars. + userAutoHide(); + } + } + + private void userAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, 350); // longer than app gesture -> flag clear. + } + + private void cancelAutoHide() { + mHandler.removeCallbacks(mAutoHide); + } + + private void scheduleAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, AUTOHIDE_TIMEOUT_MS); + } + + private void notifySystemUiVisibilityChanged(int vis) { + try { + if (mLastDispatchedSystemUiVisibility != vis) { + mWindowManagerService.statusBarVisibilityChanged(mDisplayId, vis); + mLastDispatchedSystemUiVisibility = vis; + } + } catch (RemoteException ex) { + } + } + + // ----- Methods that DisplayNavigationBarController talks to ----- + + /** Applys auto dimming animation on navigation bar when touched. */ + public void touchAutoDim() { + getBarTransitions().setAutoDim(false); + mHandler.removeCallbacks(mAutoDim); + int state = Dependency.get(StatusBarStateController.class).getState(); + if (state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED) { + mHandler.postDelayed(mAutoDim, AUTOHIDE_TIMEOUT_MS); + } + } public void setLightBarController(LightBarController lightBarController) { mLightBarController = lightBarController; @@ -811,19 +937,42 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback return mNavigationBarMode == MODE_SEMI_TRANSPARENT; } + private void checkBarModes() { + // We only have status bar on default display now. + if (mIsOnDefaultDisplay) { + mStatusBar.checkBarModes(); + } else { + checkNavBarModes(); + } + } + + /** + * Checks current navigation bar mode and make transitions. + */ + public void checkNavBarModes() { + final boolean anim = mStatusBar.isDeviceInteractive() + && mNavigationBarWindowState != WINDOW_STATE_HIDDEN; + mNavigationBarView.getBarTransitions().transitionTo(mNavigationBarMode, anim); + } + public void disableAnimationsDuringHide(long delay) { mNavigationBarView.setLayoutTransitionsEnabled(false); mNavigationBarView.postDelayed(() -> mNavigationBarView.setLayoutTransitionsEnabled(true), delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE); } - public BarTransitions getBarTransitions() { - return mNavigationBarView.getBarTransitions(); + /** + * Performs transitions on navigation bar. + * + * @param barMode transition bar mode. + * @param animate shows animations if {@code true}. + */ + public void transitionTo(@TransitionMode int barMode, boolean animate) { + getBarTransitions().transitionTo(barMode, animate); } - public void checkNavBarModes() { - mStatusBar.checkBarMode(mNavigationBarMode, - mNavigationBarWindowState, mNavigationBarView.getBarTransitions()); + private BarTransitions getBarTransitions() { + return mNavigationBarView.getBarTransitions(); } public void finishBarAnimations() { @@ -873,12 +1022,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback if (Intent.ACTION_USER_SWITCHED.equals(action)) { // The accessibility settings may be different for the new user updateAccessibilityServicesState(mAccessibilityManager); - }; + } } }; public static View create(Context context, FragmentListener listener) { - final int displayId = context.getDisplay().getDisplayId(); WindowManager.LayoutParams lp = new WindowManager.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, @@ -890,7 +1038,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback | WindowManager.LayoutParams.FLAG_SLIPPERY, PixelFormat.TRANSLUCENT); lp.token = new Binder(); - lp.setTitle("NavigationBar" + displayId); + lp.setTitle("NavigationBar" + context.getDisplayId()); lp.accessibilityTitle = context.getString(R.string.nav_bar); lp.windowAnimations = 0; 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 6a7983af862d..2fc7b78c0ca3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -276,7 +276,14 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav @Override public void onBackButtonVisibilityChanged(boolean visible) { - getBackButton().setVisibility(visible ? VISIBLE : GONE); + if (!inScreenPinning()) { + getBackButton().setVisibility(visible ? VISIBLE : GONE); + } + } + + @Override + public void onHomeButtonVisibilityChanged(boolean visible) { + getHomeButton().setVisibility(visible ? VISIBLE : GONE); } @Override @@ -670,6 +677,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav // 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(); @@ -940,6 +948,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav public void showPinningEnterExitToast(boolean entering) { if (entering) { mScreenPinningNotify.showPinningStartToast(); + + // TODO(b/112934365): remove after prototype finished, only needed to escape from pin + getBackButton().setVisibility(VISIBLE); + getHomeButton().setVisibility(VISIBLE); } else { mScreenPinningNotify.showPinningExitToast(); } 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 40ac79376b06..fb6254b0e4be 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java @@ -34,6 +34,7 @@ import java.lang.annotation.RetentionPolicy; */ public class NavigationPrototypeController extends ContentObserver { private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback"; + private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome"; static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled"; private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map"; @@ -73,6 +74,7 @@ public class NavigationPrototypeController extends ContentObserver { */ public void register() { registerObserver(HIDE_BACK_BUTTON_SETTING); + registerObserver(HIDE_HOME_BUTTON_SETTING); registerObserver(GESTURE_MATCH_SETTING); registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING); } @@ -88,22 +90,20 @@ public class NavigationPrototypeController extends ContentObserver { public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); if (!selfChange && mListener != null) { - try { - final String path = uri.getPath(); - if (path.endsWith(GESTURE_MATCH_SETTING)) { - // Get the settings gesture map corresponding to each action - // {@see updateSwipeLTRBackSetting} - updateSwipeLTRBackSetting(); - mListener.onGestureRemap(mActionMap); - } else if (path.endsWith(HIDE_BACK_BUTTON_SETTING)) { - mListener.onBackButtonVisibilityChanged( - !getGlobalBool(HIDE_BACK_BUTTON_SETTING)); - } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { - mListener.onColorAdaptChanged( - NavBarTintController.isEnabled(mContext)); - } - } catch (SettingNotFoundException e) { - e.printStackTrace(); + final String path = uri.getPath(); + if (path.endsWith(GESTURE_MATCH_SETTING)) { + // Get the settings gesture map corresponding to each action + // {@see updateSwipeLTRBackSetting} + updateSwipeLTRBackSetting(); + mListener.onGestureRemap(mActionMap); + } else if (path.endsWith(HIDE_BACK_BUTTON_SETTING)) { + mListener.onBackButtonVisibilityChanged( + !getGlobalBool(HIDE_BACK_BUTTON_SETTING, false)); + } else if (path.endsWith(HIDE_HOME_BUTTON_SETTING)) { + mListener.onHomeButtonVisibilityChanged(!hideHomeButton()); + } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { + mListener.onColorAdaptChanged( + NavBarTintController.isEnabled(mContext)); } } } @@ -117,6 +117,13 @@ public class NavigationPrototypeController extends ContentObserver { } /** + * @return if home button should be invisible + */ + boolean hideHomeButton() { + return getGlobalBool(HIDE_HOME_BUTTON_SETTING, false /* default */); + } + + /** * Since Settings.Global cannot pass arrays, use a string to represent each character as a * gesture map to actions corresponding to {@see GestureAction}. The number is represented as: * Number: [up] [down] [left] [right] @@ -131,8 +138,8 @@ public class NavigationPrototypeController extends ContentObserver { } } - private boolean getGlobalBool(String name) throws SettingNotFoundException { - return Settings.Global.getInt(mContext.getContentResolver(), name) == 1; + private boolean getGlobalBool(String name, boolean defaultVal) { + return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal ? 1 : 0) == 1; } private void registerObserver(String name) { @@ -143,6 +150,7 @@ public class NavigationPrototypeController extends ContentObserver { public interface OnPrototypeChangedListener { void onGestureRemap(@GestureAction int[] actions); void onBackButtonVisibilityChanged(boolean visible); + void onHomeButtonVisibilityChanged(boolean visible); void onColorAdaptChanged(boolean enabled); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java index b1f74c8ab91e..3839ed5d5d88 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java @@ -17,11 +17,13 @@ package com.android.systemui.statusbar.phone; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.Notification; import android.os.SystemClock; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; +import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.AmbientPulseManager; @@ -216,11 +218,17 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis } @Override - public void onEntryRemoved(Entry entry) { + public void onEntryRemoved( + @Nullable Entry entry, + String key, + StatusBarNotification old, + NotificationVisibility visibility, + boolean lifetimeExtended, + boolean removedByUser) { // Removes any alerts pending on this entry. Note that this will not stop any inflation // tasks started by a transfer, so this should only be used as clean-up for when // inflation is stopped and the pending alert no longer needs to happen. - mPendingAlerts.remove(entry.key); + mPendingAlerts.remove(key); } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index e40835fb8fd0..056c8a7f5f5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -19,14 +19,14 @@ import com.android.internal.util.ContrastColorUtil; import com.android.internal.widget.ViewClippingUtil; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.tuner.TunerService; import java.util.ArrayList; 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 c0909e3e5bd2..1b18c6cf8440 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -38,7 +38,6 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.os.PowerManager; -import android.os.SystemProperties; import android.util.AttributeSet; import android.util.Log; import android.util.MathUtils; @@ -107,23 +106,6 @@ public class NotificationPanelView extends PanelView implements private static final boolean DEBUG = false; /** - * If passive interrupts expand the NSSL or not - */ - private static final boolean EXPAND_ON_PASSIVE_INTERRUPT = SystemProperties.getBoolean( - "persist.sysui.expand_shade_on_wake_up", true); - /** - * If the notification panel should remain collapsed when the phone wakes up, even if the user - * presses power. - */ - private static final boolean NEVER_EXPAND_WHEN_WAKING_UP = SystemProperties.getBoolean( - "persist.sysui.defer_notifications_on_lock_screen", false); - /** - * If waking up the phone should take you to SHADE_LOCKED instead of KEYGUARD - */ - private static final boolean WAKE_UP_TO_SHADE = SystemProperties.getBoolean( - "persist.sysui.go_to_shade_on_wake_up", false); - - /** * Fling expanding QS. */ public static final int FLING_EXPAND = 0; @@ -283,12 +265,6 @@ public class NotificationPanelView extends PanelView implements */ private float mLinearDarkAmount; - /** - * State where the device isn't dozing anymore, but the lock screen isn't fully awake. - * The screen will be dimmed down with the shade collapsed. - */ - private boolean mSemiAwake; - private boolean mPulsing; private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger(); private boolean mNoVisibleNotifications = true; @@ -603,7 +579,6 @@ public class NotificationPanelView extends PanelView implements } mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding); mNotificationStackScroller.setAntiBurnInOffsetX(mClockPositionResult.clockX); - mKeyguardBottomArea.setBurnInXOffset(mClockPositionResult.clockX); mStackScrollerMeasuringPass++; requestScrollerTopPaddingUpdate(animate); @@ -1256,11 +1231,6 @@ public class NotificationPanelView extends PanelView implements updateDozingVisibilities(false /* animate */); } - // Expand notification shade if the device was is semi-awake state - if (mBarState == StatusBarState.SHADE && isSemiAwake()) { - mNotificationStackScroller.setDark(false /* dark */, false /* animated */, - null /* touchLocation */); - } resetVerticalPanelPosition(); updateQsState(); } @@ -2790,35 +2760,30 @@ public class NotificationPanelView extends PanelView implements mNotificationStackScroller.setAnimationsEnabled(!disabled); } - public void setDozing(boolean dozing, boolean animate, PointF wakeUpTouchLocation, - boolean passivelyInterrupted) { + /** + * Sets the dozing state. + * + * @param dozing {@code true} when dozing. + * @param animate if transition should be animated. + * @param wakeUpTouchLocation touch event location - if woken up by SLPI sensor. + */ + public void setDozing(boolean dozing, boolean animate, PointF wakeUpTouchLocation) { if (dozing == mDozing) return; mDozing = dozing; - boolean doNotExpand = (!EXPAND_ON_PASSIVE_INTERRUPT && passivelyInterrupted) - || NEVER_EXPAND_WHEN_WAKING_UP; - mSemiAwake = doNotExpand && !mDozing; - if (!mSemiAwake) { - mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation); - } + mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation); if (mBarState == StatusBarState.KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) { updateDozingVisibilities(animate); } - final float darkAmount = dozing && !mSemiAwake ? 1 : 0; - if (!mSemiAwake) { - mStatusBarStateController.setDozeAmount(darkAmount, animate); - } + final float darkAmount = dozing ? 1 : 0; + mStatusBarStateController.setDozeAmount(darkAmount, animate); if (animate) { mNotificationStackScroller.notifyDarkAnimationStart(mDozing); } } - public boolean isSemiAwake() { - return mSemiAwake; - } - @Override public void onDozeAmountChanged(float linearAmount, float amount) { mInterpolatedDarkAmount = amount; @@ -2840,6 +2805,7 @@ public class NotificationPanelView extends PanelView implements } mNotificationStackScroller.setPulsing(pulsing, animatePulse); mKeyguardStatusView.setPulsing(pulsing, animatePulse); + mKeyguardBottomArea.setPulsing(pulsing, animatePulse); } public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) { @@ -2852,7 +2818,6 @@ public class NotificationPanelView extends PanelView implements public void dozeTimeTick() { mKeyguardStatusBar.dozeTimeTick(); mKeyguardStatusView.dozeTimeTick(); - mKeyguardBottomArea.dozeTimeTick(); if (mInterpolatedDarkAmount > 0) { positionClockAndNotifications(); } @@ -3011,23 +2976,4 @@ public class NotificationPanelView extends PanelView implements public void showTransientIndication(int id) { mKeyguardBottomArea.showTransientIndication(id); } - - /** - * Whenever a user drags down on the empty area (pulling down the shade and clock) and lets go. - * - * @return {@code true} if dragging down should take the user to SHADE_LOCKED. - */ - public boolean onDraggedDown() { - if (isSemiAwake()) { - mSemiAwake = false; - mNotificationStackScroller.setDark(false /* dark */, true /* animate */, - null /* touchLocation */); - mStatusBarStateController.setDozeAmount(0f, true /* animated */); - mNotificationStackScroller.notifyDarkAnimationStart(mDozing); - mStatusBar.updateScrimController(); - - return WAKE_UP_TO_SHADE; - } - return true; - } } 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 ee1eb42a07f0..d6f2fd7a4eee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -85,7 +85,6 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceP import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.LocationController; -import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; @@ -102,9 +101,8 @@ import java.util.Locale; * strictly doesn't need to. */ public class PhoneStatusBarPolicy implements Callback, Callbacks, - RotationLockControllerCallback, Listener, LocationChangeCallback, - ZenModeController.Callback, DeviceProvisionedListener, KeyguardMonitor.Callback, - PrivacyItemController.Callback { + RotationLockControllerCallback, Listener, ZenModeController.Callback, + DeviceProvisionedListener, KeyguardMonitor.Callback, PrivacyItemController.Callback { private static final String TAG = "PhoneStatusBarPolicy"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -255,6 +253,9 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, mIconController.setIconVisibility(mSlotMicrophone, false); mIconController.setIcon(mSlotCamera, R.drawable.stat_sys_camera, null); mIconController.setIconVisibility(mSlotCamera, false); + mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID, + mContext.getString(R.string.accessibility_location_active)); + mIconController.setIconVisibility(mSlotLocation, false); mRotationLockController.addCallback(this); mBluetooth.addCallback(this); @@ -265,7 +266,6 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, mNextAlarmController.addCallback(mNextAlarmCallback); mDataSaver.addCallback(this); mKeyguardMonitor.addCallback(this); - mLocationController.addCallback(this); mPrivacyItemController.setListening(true); SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this); @@ -294,7 +294,6 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, mNextAlarmController.removeCallback(mNextAlarmCallback); mDataSaver.removeCallback(this); mKeyguardMonitor.removeCallback(this); - mLocationController.removeCallback(this); mPrivacyItemController.setListening(false); SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallback(this); mContext.unregisterReceiver(mIntentReceiver); @@ -314,21 +313,6 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, updateVolumeZen(); } - @Override - public void onLocationActiveChanged(boolean active) { - updateLocation(); - } - - // Updates the status view based on the current state of location requests. - private void updateLocation() { - if (mLocationController.isLocationActive()) { - mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID, - mContext.getString(R.string.accessibility_location_active)); - } else { - mIconController.removeAllIconsForSlot(mSlotLocation); - } - } - private void updateAlarm() { final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT); final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 2129835945d7..7a3d03fec025 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -43,9 +43,9 @@ import android.widget.LinearLayout; import com.android.systemui.Dependency; import com.android.systemui.EventLogTags; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import java.util.Objects; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 9f34cbb23131..e25c8292b637 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -93,12 +93,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo * A scrim varies its opacity based on a busyness factor, for example * how many notifications are currently visible. */ - public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f; + public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.7f; /** - * A scrim varies its opacity based on a busyness factor, for example - * how many notifications are currently visible. + * Scrim opacity when a wallpaper doesn't support ambient mode. */ - public static final float GRADIENT_SCRIM_DARK_KEYGUARD = 0.80f; + public static final float PULSING_WALLPAPER_SCRIM_ALPHA = 0.6f; + /** * The most common scrim, the one under the keyguard. */ @@ -282,8 +282,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(), AlarmTimeout.MODE_IGNORE_IF_SCHEDULED); } - // Do not re-schedule timeout when pulsing, let's save some extra battery. - } else if (mState != ScrimState.PULSING) { + } else { mTimeTicker.cancel(); mWallpaperVisibilityTimedOut = false; } @@ -365,7 +364,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mExpansionFraction = fraction; final boolean keyguardOrUnlocked = mState == ScrimState.UNLOCKED - || mState == ScrimState.KEYGUARD || mState == ScrimState.DARK_KEYGUARD; + || mState == ScrimState.KEYGUARD; if (!keyguardOrUnlocked || !mExpansionAffectsAlpha) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java index 75f81c365de1..fb3c4aa16ef5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.phone; import android.graphics.Color; -import android.os.SystemProperties; import android.os.Trace; import android.util.MathUtils; @@ -68,27 +67,6 @@ public enum ScrimState { }, /** - * On semi-awake lock screen. - */ - DARK_KEYGUARD(7) { - - @Override - public void prepare(ScrimState previousState) { - mBlankScreen = mDisplayRequiresBlanking && previousState != ScrimState.AOD; - mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP; - String opacity = SystemProperties.get("persist.sysui.aod2_scrim_opacity", "0.8"); - try { - mCurrentBehindAlpha = Float.parseFloat(opacity); - } catch (RuntimeException e) { - mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_DARK_KEYGUARD; - } - mCurrentInFrontAlpha = 0; - mCurrentInFrontTint = Color.BLACK; - mCurrentBehindTint = Color.BLACK; - } - }, - - /** * Showing password challenge on the keyguard. */ BOUNCER(1) { @@ -163,7 +141,8 @@ public enum ScrimState { @Override public float getBehindAlpha(float busyness) { - return mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f; + return mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f + : ScrimController.PULSING_WALLPAPER_SCRIM_ALPHA; } }, 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 008c21d1b936..9f0eec41bafc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -37,6 +37,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRAN import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING; +import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -71,7 +72,6 @@ import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; -import android.hardware.display.DisplayManager; import android.media.AudioAttributes; import android.metrics.LogMaker; import android.net.Uri; @@ -148,18 +148,19 @@ import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.doze.DozeReceiver; -import com.android.systemui.doze.LockScreenWakeUpController; import com.android.systemui.fragments.ExtensionFragmentListener; import com.android.systemui.fragments.FragmentHostManager; +import com.android.systemui.keyguard.KeyguardSliceProvider; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; import com.android.systemui.qs.QSFragment; import com.android.systemui.qs.QSPanel; -import com.android.systemui.qs.QSTileHost; import com.android.systemui.recents.Recents; import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -169,11 +170,11 @@ import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CrossFadeHelper; -import com.android.systemui.statusbar.DisplayNavigationBarController; import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.GestureRecorder; import com.android.systemui.statusbar.KeyboardShortcuts; import com.android.systemui.statusbar.KeyguardIndicationController; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; @@ -187,6 +188,7 @@ import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; import com.android.systemui.statusbar.notification.NotificationActivityStarter; +import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationClicker; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationData.Entry; @@ -204,7 +206,6 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; import com.android.systemui.statusbar.policy.ExtensionController; @@ -220,6 +221,7 @@ import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.util.InjectionInflationController; import com.android.systemui.volume.VolumeComponent; import java.io.FileDescriptor; @@ -228,6 +230,10 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.Map; +import javax.inject.Inject; + +import dagger.Subcomponent; + public class StatusBar extends SystemUI implements DemoMode, ActivityStarter, OnUnlockMethodChangedListener, OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback, @@ -353,6 +359,8 @@ public class StatusBar extends SystemUI implements DemoMode, private final Object mQueueLock = new Object(); protected StatusBarIconController mIconController; + @Inject + InjectionInflationController mInjectionInflater; // expanded notifications protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window @@ -385,6 +393,8 @@ public class StatusBar extends SystemUI implements DemoMode, protected AppOpsController mAppOpsController; protected KeyguardViewMediator mKeyguardViewMediator; private ZenModeController mZenController; + private final NotificationAlertingManager mNotificationAlertingManager = + Dependency.get(NotificationAlertingManager.class); // for disabling the status bar private int mDisabled1 = 0; @@ -437,18 +447,18 @@ public class StatusBar extends SystemUI implements DemoMode, protected final H mHandler = createHandler(); private int mInteractingWindows; - private boolean mAutohideSuspended; - private int mStatusBarMode; + private boolean mAutoHideSuspended; + private @TransitionMode int mStatusBarMode; private ViewMediatorCallback mKeyguardViewMediatorCallback; protected ScrimController mScrimController; protected DozeScrimController mDozeScrimController; private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); - private final Runnable mAutohide = () -> { + private final Runnable mAutoHide = () -> { int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT; if (mSystemUiVisibility != requested) { - notifyUiVisibilityChanged(requested); + notifySystemUiVisibilityChanged(requested); } }; @@ -575,11 +585,6 @@ public class StatusBar extends SystemUI implements DemoMode, } }; - protected DisplayManager mDisplayManager; - - private NavigationBarFragment mNavigationBar; - private View mNavigationBarView; - private HeadsUpAppearanceController mHeadsUpAppearanceController; private boolean mVibrateOnOpening; private VibratorHelper mVibratorHelper; @@ -587,7 +592,6 @@ public class StatusBar extends SystemUI implements DemoMode, protected NotificationPresenter mPresenter; private NotificationActivityStarter mNotificationActivityStarter; private boolean mPulsing; - private LockScreenWakeUpController mLockScreenWakeUpController; @Override public void onActiveStateChanged(int code, int uid, String packageName, boolean active) { @@ -634,9 +638,15 @@ public class StatusBar extends SystemUI implements DemoMode, mKeyguardViewMediator = getComponent(KeyguardViewMediator.class); mColorExtractor = Dependency.get(SysuiColorExtractor.class); mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - mNavigationBarController = Dependency.get(DisplayNavigationBarController.class); + mNavigationBarController = Dependency.get(NavigationBarController.class); mBubbleController = Dependency.get(BubbleController.class); mBubbleController.setExpandListener(mBubbleExpandListener); + KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance(); + if (sliceProvider != null) { + sliceProvider.initDependencies(); + } else { + Log.w(TAG, "Cannot init KeyguardSliceProvider dependencies"); + } mColorExtractor.addOnColorsChangedListener(this); mStatusBarStateController.addCallback(this, StatusBarStateController.RANK_STATUS_BAR); @@ -794,6 +804,9 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationIconAreaController.setupShelf(mNotificationShelf); Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController); + // Allow plugins to reference DarkIconDispatcher + Dependency.get(PluginDependencyProvider.class) + .allowPluginDependency(DarkIconDispatcher.class); FragmentHostManager.get(mStatusBarWindow) .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> { CollapsedStatusBarFragment statusBarFragment = @@ -854,6 +867,7 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationPanel.setHeadsUpManager(mHeadsUpManager); mGroupManager.setHeadsUpManager(mHeadsUpManager); mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager); + mNotificationLogger.setHeadsUpManager(mHeadsUpManager); putComponent(HeadsUpManager.class, mHeadsUpManager); createNavigationBar(); @@ -888,11 +902,7 @@ public class StatusBar extends SystemUI implements DemoMode, } }); - // TODO(115978725): Support light bar controller on external nav bars. mLightBarController = Dependency.get(LightBarController.class); - if (mNavigationBar != null) { - mNavigationBar.setLightBarController(mLightBarController); - } ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind); ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front); @@ -933,8 +943,6 @@ public class StatusBar extends SystemUI implements DemoMode, .withPlugin(QS.class) .withDefault(this::createDefaultQSFragment) .build()); - final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this, - mIconController); mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow, (visible) -> { mBrightnessMirrorVisible = visible; @@ -943,7 +951,6 @@ public class StatusBar extends SystemUI implements DemoMode, fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> { QS qs = (QS) f; if (qs instanceof QSFragment) { - ((QSFragment) qs).setHost(qsh); mQSPanel = ((QSFragment) qs).getQsPanel(); mQSPanel.setBrightnessMirror(mBrightnessMirrorController); } @@ -992,7 +999,6 @@ public class StatusBar extends SystemUI implements DemoMode, for (int i = 0; i < pattern.length; i++) { mCameraLaunchGestureVibePattern[i] = pattern[i]; } - mLockScreenWakeUpController = new LockScreenWakeUpController(mContext, mDozeServiceHost); // receive broadcasts IntentFilter filter = new IntentFilter(); @@ -1032,7 +1038,8 @@ public class StatusBar extends SystemUI implements DemoMode, mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel, mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController, - mScrimController, mActivityLaunchAnimator, mStatusBarKeyguardViewManager); + mScrimController, mActivityLaunchAnimator, mStatusBarKeyguardViewManager, + mNotificationAlertingManager); mAppOpsController.addCallback(APP_OPS, this); mNotificationListener.setUpWithPresenter(mPresenter); @@ -1081,25 +1088,10 @@ public class StatusBar extends SystemUI implements DemoMode, } } + // TODO(b/117478341): This was left such that CarStatusBar can override this method. + // Try to remove this. protected void createNavigationBar() { - try { - // TODO(117478341): Move this into DisplayNavigationBarController#createNavigationBars - // for-loop. We will also move the whole navigation bar logic together. - final boolean showNav = mWindowManagerService.hasNavigationBar(DEFAULT_DISPLAY); - if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav); - if (!showNav) return; - - mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> { - mNavigationBar = (NavigationBarFragment) fragment; - if (mLightBarController != null) { - mNavigationBar.setLightBarController(mLightBarController); - } - mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility); - }); - } catch (RemoteException ex) { - // no window manager? good luck with that - } - mNavigationBarController.createNavigationBars(); + mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */); } /** @@ -1108,7 +1100,7 @@ public class StatusBar extends SystemUI implements DemoMode, */ protected View.OnTouchListener getStatusBarWindowTouchListener() { return (v, event) -> { - checkUserAutohide(event); + checkUserAutoHide(event); mRemoteInputManager.checkRemoteInputOutside(event); if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mExpandedVisible) { @@ -1192,8 +1184,8 @@ public class StatusBar extends SystemUI implements DemoMode, } protected void inflateStatusBarWindow(Context context) { - mStatusBarWindow = (StatusBarWindowView) View.inflate(context, - R.layout.super_status_bar, null); + mStatusBarWindow = (StatusBarWindowView) mInjectionInflater.injectable( + LayoutInflater.from(context)).inflate(R.layout.super_status_bar, null); } protected void startKeyguard() { @@ -2089,7 +2081,7 @@ public class StatusBar extends SystemUI implements DemoMode, } // send updated sysui visibility to window manager - notifyUiVisibilityChanged(mSystemUiVisibility); + notifySystemUiVisibilityChanged(mSystemUiVisibility); } mLightBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis, @@ -2119,52 +2111,55 @@ public class StatusBar extends SystemUI implements DemoMode, } } - // TODO(115978725): Support auto hide on external nav bars. void touchAutoHide() { - // update transient bar autohide - if (mStatusBarMode == MODE_SEMI_TRANSPARENT || (mNavigationBar != null - && mNavigationBar.isSemiTransparent())) { - scheduleAutohide(); + // update transient bar auto hide + if (mStatusBarMode == MODE_SEMI_TRANSPARENT + || mNavigationBarController.isSemiTransparent(DEFAULT_DISPLAY)) { + scheduleAutoHide(); } else { - cancelAutohide(); + cancelAutoHide(); } } - protected int computeStatusBarMode(int oldVal, int newVal) { - return computeBarMode(oldVal, newVal, View.STATUS_BAR_TRANSIENT, - View.STATUS_BAR_TRANSLUCENT, View.STATUS_BAR_TRANSPARENT); + protected @TransitionMode int computeStatusBarMode(int oldVal, int newVal) { + return computeBarMode(oldVal, newVal); } protected BarTransitions getStatusBarTransitions() { return mStatusBarView.getBarTransitions(); } - protected int computeBarMode(int oldVis, int newVis, - int transientFlag, int translucentFlag, int transparentFlag) { - final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag); - final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag); + protected @TransitionMode int computeBarMode(int oldVis, int newVis) { + final int oldMode = barMode(oldVis); + final int newMode = barMode(newVis); if (oldMode == newMode) { return -1; // no mode change } return newMode; } - private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) { - int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag; - return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT - : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT - : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT - : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT - : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT - : MODE_OPAQUE; + private @TransitionMode int barMode(int vis) { + int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.STATUS_BAR_TRANSPARENT; + if ((vis & View.STATUS_BAR_TRANSIENT) != 0) { + return MODE_SEMI_TRANSPARENT; + } else if ((vis & View.STATUS_BAR_TRANSLUCENT) != 0) { + return MODE_TRANSLUCENT; + } else if ((vis & lightsOutTransparent) == lightsOutTransparent) { + return MODE_LIGHTS_OUT_TRANSPARENT; + } else if ((vis & View.STATUS_BAR_TRANSPARENT) != 0) { + return MODE_TRANSPARENT; + } else if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { + return MODE_LIGHTS_OUT; + } else { + return MODE_OPAQUE; + } } - // TODO(115978725): Support animations on external nav bars. void checkBarModes() { if (mDemoMode) return; if (mStatusBarView != null) checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions()); - if (mNavigationBar != null) mNavigationBar.checkNavBarModes(); + mNavigationBarController.checkNavBarModes(DEFAULT_DISPLAY); mNoAnimationOnNextBarModeChange = false; } @@ -2173,20 +2168,17 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationPanel.setQsScrimEnabled(scrimEnabled); } - void checkBarMode(int mode, int windowState, BarTransitions transitions) { + void checkBarMode(@TransitionMode int mode, int windowState, BarTransitions transitions) { final boolean anim = !mNoAnimationOnNextBarModeChange && mDeviceInteractive && windowState != WINDOW_STATE_HIDDEN; transitions.transitionTo(mode, anim); } - // TODO(115978725): Support animations on external nav bars. private void finishBarAnimations() { if (mStatusBarView != null) { mStatusBarView.getBarTransitions().finishAnimations(); } - if (mNavigationBar != null) { - mNavigationBar.finishBarAnimations(); - } + mNavigationBarController.finishBarAnimations(DEFAULT_DISPLAY); } private final Runnable mCheckBarModes = this::checkBarModes; @@ -2197,13 +2189,13 @@ public class StatusBar extends SystemUI implements DemoMode, ? (mInteractingWindows | barWindow) : (mInteractingWindows & ~barWindow); if (mInteractingWindows != 0) { - suspendAutohide(); + suspendAutoHide(); } else { - resumeSuspendedAutohide(); + resumeSuspendedAutoHide(); } // manually dismiss the volume panel when interacting with the nav bar if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) { - touchAutoDim(); + mNavigationBarController.touchAutoDim(DEFAULT_DISPLAY); dismissVolumeDialog(); } checkBarModes(); @@ -2215,57 +2207,42 @@ public class StatusBar extends SystemUI implements DemoMode, } } - private void resumeSuspendedAutohide() { - if (mAutohideSuspended) { - scheduleAutohide(); + private void resumeSuspendedAutoHide() { + if (mAutoHideSuspended) { + scheduleAutoHide(); mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher } } - private void suspendAutohide() { - mHandler.removeCallbacks(mAutohide); + private void suspendAutoHide() { + mHandler.removeCallbacks(mAutoHide); mHandler.removeCallbacks(mCheckBarModes); - mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0; + mAutoHideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0; } - private void cancelAutohide() { - mAutohideSuspended = false; - mHandler.removeCallbacks(mAutohide); + private void cancelAutoHide() { + mAutoHideSuspended = false; + mHandler.removeCallbacks(mAutoHide); } - private void scheduleAutohide() { - cancelAutohide(); - mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS); - } - - public void touchAutoDim() { - if (mNavigationBar != null) { - mNavigationBar.getBarTransitions().setAutoDim(false); - } - mHandler.removeCallbacks(mAutoDim); - - // Do not dim the navigation buttons if the its tint is controlled by the bar's background - if (NavBarTintController.isEnabled(mContext)) { - return; - } - if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) { - mHandler.postDelayed(mAutoDim, AUTOHIDE_TIMEOUT_MS); - } + private void scheduleAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, AUTOHIDE_TIMEOUT_MS); } - void checkUserAutohide(MotionEvent event) { + void checkUserAutoHide(MotionEvent event) { if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar && event.getX() == 0 && event.getY() == 0 // a touch outside both bars && !mRemoteInputManager.getController() .isRemoteInputActive()) { // not due to typing in IME - userAutohide(); + userAutoHide(); } } - private void userAutohide() { - cancelAutohide(); - mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear + private void userAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, 350); // longer than app gesture -> flag clear } private boolean areLightsOn() { @@ -2284,11 +2261,10 @@ public class StatusBar extends SystemUI implements DemoMode, } } - private void notifyUiVisibilityChanged(int vis) { + private void notifySystemUiVisibilityChanged(int vis) { try { if (mLastDispatchedSystemUiVisibility != vis) { - // TODO (b/117478341): Resolve one status bar/ navigation bar assumption - mWindowManagerService.statusBarVisibilityChanged(Display.DEFAULT_DISPLAY, vis); + mWindowManagerService.statusBarVisibilityChanged(DEFAULT_DISPLAY, vis); mLastDispatchedSystemUiVisibility = vis; } } catch (RemoteException ex) { @@ -2913,10 +2889,6 @@ public class StatusBar extends SystemUI implements DemoMode, mWindowManager.removeViewImmediate(mStatusBarWindow); mStatusBarWindow = null; } - if (mNavigationBarView != null) { - mWindowManager.removeViewImmediate(mNavigationBarView); - mNavigationBarView = null; - } mNavigationBarController.destroy(); mContext.unregisterReceiver(mBroadcastReceiver); mContext.unregisterReceiver(mDemoReceiver); @@ -2986,15 +2958,12 @@ public class StatusBar extends SystemUI implements DemoMode, "transparent".equals(mode) ? MODE_TRANSPARENT : "warning".equals(mode) ? MODE_WARNING : -1; - // TODO(115978725): Support external nav bar transitions if (barMode != -1) { boolean animate = true; if (mStatusBarView != null) { mStatusBarView.getBarTransitions().transitionTo(barMode, animate); } - if (mNavigationBar != null) { - mNavigationBar.getBarTransitions().transitionTo(barMode, animate); - } + mNavigationBarController.transitionTo(DEFAULT_DISPLAY, barMode, animate); } } if (modeChange || command.equals(COMMAND_OPERATOR)) { @@ -3220,12 +3189,9 @@ public class StatusBar extends SystemUI implements DemoMode, mDraggedDownEntry = null; } - // TODO(115978725): Support animations on external nav bars. // Disable layout transitions in navbar for this transition because the load is just // too heavy for the CPU and GPU on any device. - if (mNavigationBar != null) { - mNavigationBar.disableAnimationsDuringHide(delay); - } + mNavigationBarController.disableAnimationsDuringHide(DEFAULT_DISPLAY, delay); } else if (!mNotificationPanel.isCollapsing()) { instantCollapseNotificationPanel(); } @@ -3312,12 +3278,7 @@ public class StatusBar extends SystemUI implements DemoMode, boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup()) || (mDozing && mDozeServiceHost.shouldAnimateScreenOff() && sleepingFromKeyguard); - mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation, - mDozeServiceHost.wasPassivelyInterrupted()); - if (mNotificationPanel.isSemiAwake() - && SystemProperties.getBoolean("persist.systemui.show_swipe_up", false)) { - mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock); - } + mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation); updateQsExpansionEnabled(); Trace.endSection(); } @@ -3460,7 +3421,7 @@ public class StatusBar extends SystemUI implements DemoMode, updateReportRejectedTouchVisibility(); updateDozing(); updateTheme(); - touchAutoDim(); + mNavigationBarController.touchAutoDim(DEFAULT_DISPLAY); Trace.beginSection("StatusBar#updateKeyguardState"); if (mState == StatusBarState.KEYGUARD) { mKeyguardIndicationController.setVisible(true); @@ -3581,11 +3542,7 @@ public class StatusBar extends SystemUI implements DemoMode, // TODO: Figure out way to remove these. public NavigationBarView getNavigationBarView() { - return (mNavigationBar != null ? (NavigationBarView) mNavigationBar.getView() : null); - } - - public View getNavigationBarWindow() { - return mNavigationBarView; + return mNavigationBarController.getDefaultNavigationBarView(); } /** @@ -3883,9 +3840,6 @@ public class StatusBar extends SystemUI implements DemoMode, // FLAG_DISMISS_KEYGUARD_ACTIVITY. ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming() ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER; - if (mNotificationPanel.isSemiAwake()) { - state = ScrimState.DARK_KEYGUARD; - } mScrimController.transitionTo(state); } else if (isInLaunchTransition() || mLaunchCameraOnScreenTurningOn || launchingAffordanceWithPreview) { @@ -3898,8 +3852,7 @@ public class StatusBar extends SystemUI implements DemoMode, } else if (mDozing && !wakeAndUnlocking) { mScrimController.transitionTo(ScrimState.AOD); } else if (mIsKeyguard && !wakeAndUnlocking) { - mScrimController.transitionTo(mNotificationPanel.isSemiAwake() - ? ScrimState.DARK_KEYGUARD : ScrimState.KEYGUARD); + mScrimController.transitionTo(ScrimState.KEYGUARD); } else if (mBubbleController.isStackExpanded()) { mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED); } else { @@ -3922,7 +3875,6 @@ public class StatusBar extends SystemUI implements DemoMode, private boolean mAnimateWakeup; private boolean mAnimateScreenOff; private boolean mIgnoreTouchWhilePulsing; - private boolean mPassivelyInterrupted; @Override public String toString() { @@ -4014,11 +3966,6 @@ public class StatusBar extends SystemUI implements DemoMode, } @Override - public void setPassiveInterrupt(boolean passiveInterrupt) { - mPassivelyInterrupted = passiveInterrupt; - } - - @Override public void onIgnoreTouchWhilePulsing(boolean ignore) { if (ignore != mIgnoreTouchWhilePulsing) { DozeLog.tracePulseTouchDisabledByProx(mContext, ignore); @@ -4065,11 +4012,6 @@ public class StatusBar extends SystemUI implements DemoMode, } @Override - public void startPendingIntentDismissingKeyguard(PendingIntent intent) { - StatusBar.this.startPendingIntentDismissingKeyguard(intent); - } - - @Override public void extendPulse() { if (mDozeScrimController.isPulsing() && mAmbientPulseManager.hasNotifications()) { mAmbientPulseManager.extendPulse(); @@ -4079,6 +4021,13 @@ public class StatusBar extends SystemUI implements DemoMode, } @Override + public void stopPulsing() { + if (mDozeScrimController.isPulsing()) { + mDozeScrimController.pulseOutNow(); + } + } + + @Override public void setAnimateWakeup(boolean animateWakeup) { if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING) { @@ -4131,10 +4080,6 @@ public class StatusBar extends SystemUI implements DemoMode, public boolean shouldAnimateScreenOff() { return mAnimateScreenOff; } - - public boolean wasPassivelyInterrupted() { - return mPassivelyInterrupted; - } } public boolean shouldIgnoreTouch() { @@ -4179,7 +4124,7 @@ public class StatusBar extends SystemUI implements DemoMode, private DeviceProvisionedController mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - protected DisplayNavigationBarController mNavigationBarController; + protected NavigationBarController mNavigationBarController; // UI-specific methods @@ -4507,14 +4452,12 @@ public class StatusBar extends SystemUI implements DemoMode, } // End Extra BaseStatusBarMethods. - // TODO(115978725): Handle dimming for external nav bars - private final Runnable mAutoDim = () -> { - if (mNavigationBar != null) { - mNavigationBar.getBarTransitions().setAutoDim(true); - } - }; - public NotificationGutsManager getGutsManager() { return mGutsManager; } + + @Subcomponent + public interface StatusBarInjector { + void createStatusBar(StatusBar statusbar); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java index 26c9d288494d..2e2ff1a5750e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -38,14 +38,14 @@ import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.DemoMode; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarMobileView; import com.android.systemui.statusbar.StatusBarWifiView; import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.util.Utils.DisableStateTracker; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java index 4f25349ef7d2..db7589d0f333 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java @@ -45,11 +45,15 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Receives the callbacks from CommandQueue related to icons and tracks the state of * all the icons. Dispatches this state to any IconManagers that are currently * registered with it. */ +@Singleton public class StatusBarIconControllerImpl extends StatusBarIconList implements Tunable, ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController { @@ -66,6 +70,7 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu private boolean mIsDark = false; + @Inject public StatusBarIconControllerImpl(Context context) { super(context.getResources().getStringArray( com.android.internal.R.array.config_statusBarIcons)); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index d643f07e2859..7b7bcb448022 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -20,6 +20,7 @@ import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.SPEW; +import android.annotation.Nullable; import android.app.KeyguardManager; import android.content.Context; import android.content.pm.PackageManager; @@ -37,6 +38,7 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.widget.MessagingGroup; import com.android.internal.widget.MessagingMessage; import com.android.keyguard.KeyguardUpdateMonitor; @@ -56,11 +58,13 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.AboveShelfObserver; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; +import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationData.Entry; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; import com.android.systemui.statusbar.notification.NotificationRowBinder; +import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; @@ -97,6 +101,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, Dependency.get(NotificationInterruptionStateProvider.class); private final NotificationMediaManager mMediaManager = Dependency.get(NotificationMediaManager.class); + private final VisualStabilityManager mVisualStabilityManager = + Dependency.get(VisualStabilityManager.class); protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class); private final NotificationPanelView mNotificationPanel; @@ -129,7 +135,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, DozeScrimController dozeScrimController, ScrimController scrimController, ActivityLaunchAnimator activityLaunchAnimator, - StatusBarKeyguardViewManager statusBarKeyguardViewManager) { + StatusBarKeyguardViewManager statusBarKeyguardViewManager, + NotificationAlertingManager notificationAlertingManager) { mContext = context; mNotificationPanel = panel; mHeadsUpManager = headsUp; @@ -181,37 +188,52 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, } @Override - public void onNotificationUpdated(StatusBarNotification notification) { + public void onEntryUpdated(Entry entry) { mShadeController.updateAreThereNotifications(); } @Override - public void onNotificationRemoved(String key, StatusBarNotification old) { - StatusBarNotificationPresenter.this.onNotificationRemoved(key, old); - } - - @Override - public void onPerformRemoveNotification( - StatusBarNotification statusBarNotification) { - StatusBarNotificationPresenter.this.onPerformRemoveNotification(); + public void onEntryRemoved( + @Nullable Entry entry, + String key, + StatusBarNotification old, + NotificationVisibility visibility, + boolean lifetimeExtended, + boolean removedByUser) { + if (!lifetimeExtended) { + StatusBarNotificationPresenter.this.onNotificationRemoved(key, old); + } + if (removedByUser) { + maybeEndAmbientPulse(); + } } }; + NotificationGutsManager gutsManager = Dependency.get(NotificationGutsManager.class); + mViewHierarchyManager.setUpWithPresenter(this, notifListContainer); - mEntryManager.setUpWithPresenter( - this, notifListContainer, notificationEntryListener, mHeadsUpManager); + mEntryManager.setUpWithPresenter(this, notifListContainer, mHeadsUpManager); + mEntryManager.addNotificationEntryListener(notificationEntryListener); + mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager); + mEntryManager.addNotificationLifetimeExtender(mAmbientPulseManager); + mEntryManager.addNotificationLifetimeExtender(gutsManager); + mEntryManager.addNotificationLifetimeExtenders( + remoteInputManager.getLifetimeExtenders()); mNotificationRowBinder.setUpWithPresenter(this, notifListContainer, mHeadsUpManager, mEntryManager, this); mNotificationInterruptionStateProvider.setUpWithPresenter( this, mHeadsUpManager, this::canHeadsUp); mLockscreenUserManager.setUpWithPresenter(this); mMediaManager.setUpWithPresenter(this); - Dependency.get(NotificationGutsManager.class).setUpWithPresenter(this, + mVisualStabilityManager.setUpWithPresenter(this); + gutsManager.setUpWithPresenter(this, notifListContainer, mCheckSaveListener, mOnSettingsClickListener); onUserSwitched(mLockscreenUserManager.getCurrentUserId()); }); Dependency.get(ConfigurationController.class).addCallback(this); + + notificationAlertingManager.setHeadsUpManager(mHeadsUpManager); } @Override @@ -253,7 +275,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, || mActivityLaunchAnimator.isAnimationRunning(); } - private void onPerformRemoveNotification() { + private void maybeEndAmbientPulse() { if (mNotificationPanel.hasPulsingNotifications() && !mAmbientPulseManager.hasNotifications()) { // We were showing a pulse for a notification, but no notifications are pulsing anymore. 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 78f537459d0a..116ecc8ddeb5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java @@ -47,6 +47,12 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.PreviewInflater; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class StatusBarRemoteInputCallback implements Callback, Callbacks { private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); @@ -65,6 +71,9 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks { private int mDisabled2; protected BroadcastReceiver mChallengeReceiver = new ChallengeReceiver(); + /** + */ + @Inject public StatusBarRemoteInputCallback(Context context) { mContext = context; mContext.registerReceiverAsUser(mChallengeReceiver, UserHandle.ALL, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java index cb6e30070fdd..88f904882c8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java @@ -54,9 +54,13 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.reflect.Field; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Encapsulates all logic for the status bar window state management. */ +@Singleton public class StatusBarWindowController implements Callback, Dumpable, ConfigurationListener { private static final String TAG = "StatusBarWindowController"; @@ -78,6 +82,7 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class); + @Inject public StatusBarWindowController(Context context) { this(context, context.getSystemService(WindowManager.class), ActivityManager.getService(), DozeParameters.getInstance(context)); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SysuiDarkIconDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SysuiDarkIconDispatcher.java new file mode 100644 index 000000000000..d53772127601 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SysuiDarkIconDispatcher.java @@ -0,0 +1,32 @@ +/* + * 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.statusbar.phone; + +import com.android.systemui.Dumpable; +import com.android.systemui.plugins.DarkIconDispatcher; + +/** + * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area + * and dark intensity. + */ +public interface SysuiDarkIconDispatcher extends DarkIconDispatcher, Dumpable { + + /** + * @return LightBarTransitionsController + */ + LightBarTransitionsController getTransitionsController(); +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityController.java index cc431dd3c34a..ebfdb3f9aa76 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityController.java @@ -23,6 +23,12 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class AccessibilityController implements AccessibilityManager.AccessibilityStateChangeListener, AccessibilityManager.TouchExplorationStateChangeListener { @@ -32,6 +38,9 @@ public class AccessibilityController implements private boolean mAccessibilityEnabled; private boolean mTouchExplorationEnabled; + /** + */ + @Inject public AccessibilityController(Context context) { AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java index 67da8a54b68a..1395e1377529 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java @@ -19,14 +19,19 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * For mocking because AccessibilityManager is final for some reason... */ +@Singleton public class AccessibilityManagerWrapper implements CallbackController<AccessibilityServicesStateChangeListener> { private final AccessibilityManager mAccessibilityManager; + @Inject public AccessibilityManagerWrapper(Context context) { mAccessibilityManager = context.getSystemService(AccessibilityManager.class); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java index ddcfbf6f3c31..6190c8fff8cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java @@ -30,7 +30,6 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.settingslib.utils.PowerUtil; -import com.android.systemui.Dependency; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.Estimate; @@ -39,10 +38,14 @@ import java.io.PrintWriter; import java.text.NumberFormat; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Default implementation of a {@link BatteryController}. This controller monitors for battery * level change events that are broadcasted by the system. */ +@Singleton public class BatteryControllerImpl extends BroadcastReceiver implements BatteryController { private static final String TAG = "BatteryController"; @@ -51,7 +54,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int UPDATE_GRANULARITY_MSEC = 1000 * 60; - private final EnhancedEstimates mEstimates = Dependency.get(EnhancedEstimates.class); + private final EnhancedEstimates mEstimates; private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>(); private final PowerManager mPowerManager; private final Handler mHandler; @@ -68,15 +71,18 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC private Estimate mEstimate; private long mLastEstimateTimestamp = -1; - public BatteryControllerImpl(Context context) { - this(context, context.getSystemService(PowerManager.class)); + @Inject + public BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates) { + this(context, enhancedEstimates, context.getSystemService(PowerManager.class)); } @VisibleForTesting - BatteryControllerImpl(Context context, PowerManager powerManager) { + BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates, + PowerManager powerManager) { mContext = context; mHandler = new Handler(); mPowerManager = powerManager; + mEstimates = enhancedEstimates; registerReceiver(); updatePowerSave(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java index 6f64a563289e..8916242b682b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.policy; +import static com.android.systemui.Dependency.BG_LOOPER_NAME; + +import android.annotation.Nullable; import android.app.ActivityManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -32,7 +35,6 @@ import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; -import com.android.systemui.Dependency; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -42,6 +44,13 @@ import java.util.Collection; import java.util.List; import java.util.WeakHashMap; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +/** + */ +@Singleton public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback, CachedBluetoothDevice.Callback, LocalBluetoothProfileManager.ServiceListener { private static final String TAG = "BluetoothController"; @@ -61,8 +70,12 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa private final H mHandler = new H(Looper.getMainLooper()); private int mState; - public BluetoothControllerImpl(Context context, Looper bgLooper) { - mLocalBluetoothManager = Dependency.get(LocalBluetoothManager.class); + /** + */ + @Inject + public BluetoothControllerImpl(Context context, @Named(BG_LOOPER_NAME) Looper bgLooper, + @Nullable LocalBluetoothManager localBluetoothManager) { + mLocalBluetoothManager = localBluetoothManager; mBgHandler = new Handler(bgLooper); if (mLocalBluetoothManager != null) { mLocalBluetoothManager.getEventManager().registerCallback(this); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java index ccfe073d5cb8..c7d337ad46d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java @@ -44,8 +44,12 @@ import java.util.Objects; import java.util.Set; import java.util.UUID; +import javax.inject.Inject; +import javax.inject.Singleton; + /** Platform implementation of the cast controller. **/ +@Singleton public class CastControllerImpl implements CastController { private static final String TAG = "CastController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -63,6 +67,7 @@ public class CastControllerImpl implements CastController { private boolean mCallbackRegistered; private MediaProjectionInfo mProjection; + @Inject public CastControllerImpl(Context context) { mContext = context; mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index aafdcd50b8e8..5eb3e8950690 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -44,11 +44,12 @@ import com.android.systemui.Dependency; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java index 4a1175489c5e..54502e41ca64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java @@ -24,10 +24,10 @@ import android.util.Slog; import android.view.MotionEvent; import android.view.Surface; +import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.NavigationBarView; -import com.android.systemui.statusbar.phone.StatusBar; /** * The "dead zone" consumes unintentional taps along the top edge of the navigation bar. @@ -44,7 +44,7 @@ public class DeadZone { public static final int VERTICAL = 1; // Consume taps along the left edge. private static final boolean CHATTY = true; // print to logcat when we eat a click - private final StatusBar mStatusBar; + private final NavigationBarController mNavBarController; private final NavigationBarView mNavigationBarView; private boolean mShouldFlash; @@ -58,6 +58,7 @@ public class DeadZone { private boolean mVertical; private long mLastPokeTime; private int mDisplayRotation; + private final int mDisplayId; private final Runnable mDebugFlash = new Runnable() { @Override @@ -68,8 +69,8 @@ public class DeadZone { public DeadZone(NavigationBarView view) { mNavigationBarView = view; - mStatusBar = SysUiServiceProvider.getComponent(mNavigationBarView.getContext(), - StatusBar.class); + mNavBarController = Dependency.get(NavigationBarController.class); + mDisplayId = view.getContext().getDisplayId(); onConfigurationChanged(HORIZONTAL); } @@ -133,7 +134,7 @@ public class DeadZone { if (DEBUG) { Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY()); } - if (mStatusBar != null) mStatusBar.touchAutoDim(); + mNavBarController.touchAutoDim(mDisplayId); int size = (int) getSize(event.getEventTime()); // In the vertical orientation consume taps along the left edge. // In horizontal orientation consume taps along the top edge. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java index f2283a53a608..f5e745f650a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java @@ -14,6 +14,8 @@ package com.android.systemui.statusbar.policy; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; @@ -21,12 +23,19 @@ import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings.Global; import android.provider.Settings.Secure; +import android.os.Handler; -import com.android.systemui.Dependency; import com.android.systemui.settings.CurrentUserTracker; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +/** + */ +@Singleton public class DeviceProvisionedControllerImpl extends CurrentUserTracker implements DeviceProvisionedController { @@ -35,13 +44,28 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen private final Context mContext; private final Uri mDeviceProvisionedUri; private final Uri mUserSetupUri; + protected final ContentObserver mSettingsObserver; - public DeviceProvisionedControllerImpl(Context context) { + /** + */ + @Inject + public DeviceProvisionedControllerImpl(Context context, + @Named(MAIN_HANDLER_NAME) Handler mainHandler) { super(context); mContext = context; mContentResolver = context.getContentResolver(); mDeviceProvisionedUri = Global.getUriFor(Global.DEVICE_PROVISIONED); mUserSetupUri = Secure.getUriFor(Secure.USER_SETUP_COMPLETE); + mSettingsObserver = new ContentObserver(mainHandler) { + @Override + public void onChange(boolean selfChange, Uri uri, int userId) { + if (mUserSetupUri.equals(uri)) { + notifySetupChanged(); + } else { + notifyProvisionedChanged(); + } + } + }; } @Override @@ -118,17 +142,4 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen mListeners.get(i).onDeviceProvisionedChanged(); } } - - protected final ContentObserver mSettingsObserver = new ContentObserver(Dependency.get( - Dependency.MAIN_HANDLER)) { - - @Override - public void onChange(boolean selfChange, Uri uri, int userId) { - if (mUserSetupUri.equals(uri)) { - notifySetupChanged(); - } else { - notifyProvisionedChanged(); - } - } - }; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java index a6146a625193..fd030d133be0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java @@ -19,7 +19,6 @@ import android.content.res.Configuration; import android.os.Handler; import android.util.ArrayMap; -import com.android.systemui.Dependency; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginManager; @@ -34,6 +33,12 @@ import java.util.Comparator; import java.util.function.Consumer; import java.util.function.Supplier; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class ExtensionControllerImpl implements ExtensionController { public static final int SORT_ORDER_PLUGIN = 0; @@ -43,9 +48,24 @@ public class ExtensionControllerImpl implements ExtensionController { public static final int SORT_ORDER_DEFAULT = 4; private final Context mDefaultContext; - - public ExtensionControllerImpl(Context context) { + private final LeakDetector mLeakDetector; + private final PluginManager mPluginManager; + private final TunerService mTunerService; + private final ConfigurationController mConfigurationController; + + /** + */ + @Inject + public ExtensionControllerImpl(Context context, + LeakDetector leakDetector, + PluginManager pluginManager, + TunerService tunerService, + ConfigurationController configurationController) { mDefaultContext = context; + mLeakDetector = leakDetector; + mPluginManager = pluginManager; + mTunerService = tunerService; + mConfigurationController = configurationController; } @Override @@ -159,14 +179,14 @@ public class ExtensionControllerImpl implements ExtensionController { @Override public void clearItem(boolean isDestroyed) { if (isDestroyed && mItem != null) { - Dependency.get(LeakDetector.class).trackGarbage(mItem); + mLeakDetector.trackGarbage(mItem); } mItem = null; } private void notifyChanged() { if (mItem != null) { - Dependency.get(LeakDetector.class).trackGarbage(mItem); + mLeakDetector.trackGarbage(mItem); } mItem = null; for (int i = 0; i < mProducers.size(); i++) { @@ -207,7 +227,7 @@ public class ExtensionControllerImpl implements ExtensionController { public PluginItem(String action, Class<P> cls, PluginConverter<T, P> converter) { mConverter = converter; - Dependency.get(PluginManager.class).addPluginListener(action, this, cls); + mPluginManager.addPluginListener(action, this, cls); } @Override @@ -235,7 +255,7 @@ public class ExtensionControllerImpl implements ExtensionController { @Override public void destroy() { - Dependency.get(PluginManager.class).removePluginListener(this); + mPluginManager.removePluginListener(this); } @Override @@ -251,7 +271,7 @@ public class ExtensionControllerImpl implements ExtensionController { public TunerItem(TunerFactory<T> factory, String... setting) { mFactory = factory; - Dependency.get(TunerService.class).addTunable(this, setting); + mTunerService.addTunable(this, setting); } @Override @@ -261,7 +281,7 @@ public class ExtensionControllerImpl implements ExtensionController { @Override public void destroy() { - Dependency.get(TunerService.class).removeTunable(this); + mTunerService.removeTunable(this); } @Override @@ -289,7 +309,7 @@ public class ExtensionControllerImpl implements ExtensionController { mSupplier = supplier; mUiMode = mDefaultContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK; - Dependency.get(ConfigurationController.class).addCallback(this); + mConfigurationController.addCallback(this); } @Override @@ -309,7 +329,7 @@ public class ExtensionControllerImpl implements ExtensionController { @Override public void destroy() { - Dependency.get(ConfigurationController.class).removeCallback(this); + mConfigurationController.removeCallback(this); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java index e23ce2d022b3..41ff9d1029b2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java @@ -35,9 +35,13 @@ import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Manages the flashlight. */ +@Singleton public class FlashlightControllerImpl implements FlashlightController { private static final String TAG = "FlashlightController"; @@ -64,6 +68,7 @@ public class FlashlightControllerImpl implements FlashlightController { private String mCameraId; private boolean mTorchAvailable; + @Inject public FlashlightControllerImpl(Context context) { mContext = context; mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index 0a72c3f9e8d8..b561ac1664c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -16,19 +16,27 @@ package com.android.systemui.statusbar.policy; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + import android.app.ActivityManager; import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; +import android.os.Handler; import android.os.UserManager; import android.util.Log; -import com.android.systemui.Dependency; - import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +/** + */ +@Singleton public class HotspotControllerImpl implements HotspotController, WifiManager.SoftApCallback { private static final String TAG = "HotspotController"; @@ -37,17 +45,22 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof private final ArrayList<Callback> mCallbacks = new ArrayList<>(); private final ConnectivityManager mConnectivityManager; private final WifiManager mWifiManager; + private final Handler mMainHandler; private final Context mContext; private int mHotspotState; private int mNumConnectedDevices; private boolean mWaitingForTerminalState; - public HotspotControllerImpl(Context context) { + /** + */ + @Inject + public HotspotControllerImpl(Context context, @Named(MAIN_HANDLER_NAME) Handler mainHandler) { mContext = context; mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + mMainHandler = mainHandler; } @Override @@ -109,10 +122,13 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof * @param shouldListen whether we should start listening to various wifi statuses */ private void updateWifiStateListeners(boolean shouldListen) { + if (mWifiManager == null) { + return; + } if (shouldListen) { mWifiManager.registerSoftApCallback( this, - Dependency.get(Dependency.MAIN_HANDLER)); + mMainHandler); } else { mWifiManager.unregisterSoftApCallback(this); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java index aee021ce4688..ba6369e2c90e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java @@ -18,6 +18,7 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_STATUS_ICONS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.STATUS_BAR_ICONS_CHANGED; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION; +import static com.android.systemui.Dependency.BG_LOOPER_NAME; import android.content.Context; import android.metrics.LogMaker; @@ -32,6 +33,9 @@ import com.android.internal.logging.MetricsLogger; import java.util.Arrays; import java.util.List; +import javax.inject.Inject; +import javax.inject.Named; + public class IconLoggerImpl implements IconLogger { // Minimum ms between log statements. @@ -46,7 +50,9 @@ public class IconLoggerImpl implements IconLogger { private final List<String> mIconIndex; private long mLastLog = System.currentTimeMillis(); - public IconLoggerImpl(Context context, Looper bgLooper, MetricsLogger logger) { + @Inject + public IconLoggerImpl(Context context, @Named(BG_LOOPER_NAME) Looper bgLooper, + MetricsLogger logger) { mContext = context; mHandler = new Handler(bgLooper); mLogger = logger; 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 5eb0fb76794d..3c8ed6ebf279 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java @@ -25,6 +25,12 @@ import com.android.systemui.settings.CurrentUserTracker; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback implements KeyguardMonitor { @@ -47,6 +53,9 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback private boolean mKeyguardGoingAway; private boolean mLaunchTransitionFadingAway; + /** + */ + @Inject public KeyguardMonitorImpl(Context context) { mContext = context; mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java index 840e77ea85a2..683cdbb326dc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import static com.android.settingslib.Utils.updateLocationEnabled; +import static com.android.systemui.Dependency.BG_LOOPER_NAME; import android.app.ActivityManager; import android.app.AppOpsManager; @@ -40,9 +41,14 @@ import com.android.systemui.util.Utils; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + /** * A controller to manage changes of location related states and update the views accordingly. */ +@Singleton public class LocationControllerImpl extends BroadcastReceiver implements LocationController { private static final int[] mHighPowerRequestAppOpArray @@ -59,7 +65,8 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio new ArrayList<LocationChangeCallback>(); private final H mHandler = new H(); - public LocationControllerImpl(Context context, Looper bgLooper) { + @Inject + public LocationControllerImpl(Context context, @Named(BG_LOOPER_NAME) Looper bgLooper) { mContext = context; // Register to listen for changes in location settings. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index bc43120fcefa..9422101c76dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -22,6 +22,8 @@ import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE; import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT; +import static com.android.systemui.Dependency.BG_LOOPER_NAME; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -65,7 +67,6 @@ import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGr import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.BitSet; import java.util.Collections; import java.util.Comparator; @@ -74,7 +75,12 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + /** Platform implementation of the network controller. **/ +@Singleton public class NetworkControllerImpl extends BroadcastReceiver implements NetworkController, DemoMode, DataUsageController.NetworkNameProvider, ConfigurationChangedReceiver, Dumpable { @@ -154,7 +160,8 @@ public class NetworkControllerImpl extends BroadcastReceiver /** * Construct this controller object and register for updates. */ - public NetworkControllerImpl(Context context, Looper bgLooper, + @Inject + public NetworkControllerImpl(Context context, @Named(BG_LOOPER_NAME) Looper bgLooper, DeviceProvisionedController deviceProvisionedController) { this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE), (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java index dac878c69313..288b3aff2af6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java @@ -27,6 +27,13 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Implementation of {@link NextAlarmController} + */ +@Singleton public class NextAlarmControllerImpl extends BroadcastReceiver implements NextAlarmController { @@ -35,6 +42,9 @@ public class NextAlarmControllerImpl extends BroadcastReceiver private AlarmManager mAlarmManager; private AlarmManager.AlarmClockInfo mNextAlarm; + /** + */ + @Inject public NextAlarmControllerImpl(Context context) { mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); IntentFilter filter = new IntentFilter(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.java index 2a10db620096..630bd18c6ad6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.java @@ -21,7 +21,6 @@ import android.content.Context; import android.content.res.Configuration; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.Dependency; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.qs.QSFragment; import com.android.systemui.statusbar.CommandQueue; @@ -44,11 +43,12 @@ public class RemoteInputQuickSettingsDisabler @VisibleForTesting CommandQueue mCommandQueue; @Inject - public RemoteInputQuickSettingsDisabler(Context context) { + public RemoteInputQuickSettingsDisabler(Context context, + ConfigurationController configController) { mContext = context; mCommandQueue = SysUiServiceProvider.getComponent(context, CommandQueue.class); mLastOrientation = mContext.getResources().getConfiguration().orientation; - Dependency.get(ConfigurationController.class).addCallback(this); + configController.addCallback(this); } public int adjustDisableFlags(int state) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java index 5418dc14e0bb..1f368e164678 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java @@ -23,7 +23,11 @@ import com.android.internal.view.RotationPolicy; import java.util.concurrent.CopyOnWriteArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + /** Platform implementation of the rotation lock controller. **/ +@Singleton public final class RotationLockControllerImpl implements RotationLockController { private final Context mContext; private final CopyOnWriteArrayList<RotationLockControllerCallback> mCallbacks = @@ -37,6 +41,7 @@ public final class RotationLockControllerImpl implements RotationLockController } }; + @Inject public RotationLockControllerImpl(Context context) { mContext = context; setListening(true); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index 29a6b956ed1e..d88ae78c5afb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -15,6 +15,8 @@ */ package com.android.systemui.statusbar.policy; +import static com.android.systemui.Dependency.BG_HANDLER_NAME; + import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; @@ -47,7 +49,6 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.settings.CurrentUserTracker; @@ -55,6 +56,13 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +/** + */ +@Singleton public class SecurityControllerImpl extends CurrentUserTracker implements SecurityController { private static final String TAG = "SecurityController"; @@ -78,6 +86,7 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi private final DevicePolicyManager mDevicePolicyManager; private final PackageManager mPackageManager; private final UserManager mUserManager; + private final Handler mBgHandler; @GuardedBy("mCallbacks") private final ArrayList<SecurityControllerCallback> mCallbacks = new ArrayList<>(); @@ -90,13 +99,18 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi // Needs to be cached here since the query has to be asynchronous private ArrayMap<Integer, Boolean> mHasCACerts = new ArrayMap<Integer, Boolean>(); - public SecurityControllerImpl(Context context) { - this(context, null); + /** + */ + @Inject + public SecurityControllerImpl(Context context, @Named(BG_HANDLER_NAME) Handler bgHandler) { + this(context, bgHandler, null); } - public SecurityControllerImpl(Context context, SecurityControllerCallback callback) { + public SecurityControllerImpl(Context context, Handler bgHandler, + SecurityControllerCallback callback) { super(context); mContext = context; + mBgHandler = bgHandler; mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); mConnectivityManager = (ConnectivityManager) @@ -112,7 +126,7 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi IntentFilter filter = new IntentFilter(); filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, - new Handler(Dependency.get(Dependency.BG_LOOPER))); + bgHandler); // TODO: re-register network callback on user change. mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback); @@ -404,7 +418,7 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi return new Pair<Integer, Boolean>(userId[0], hasCACerts); } catch (RemoteException | InterruptedException | AssertionError e) { Log.i(TAG, "failed to get CA certs", e); - new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed( + mBgHandler.postDelayed( () -> new CACertLoader().execute(userId[0]), CA_CERT_LOADING_RETRY_TIME_IN_MS); return new Pair<Integer, Boolean>(userId[0], null); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java index fed803217568..0ca6ff6ec66e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java @@ -40,6 +40,12 @@ import com.android.systemui.R; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + */ +@Singleton public class UserInfoControllerImpl implements UserInfoController { private static final String TAG = "UserInfoController"; @@ -53,6 +59,9 @@ public class UserInfoControllerImpl implements UserInfoController { private Drawable mUserDrawable; private String mUserAccount; + /** + */ + @Inject public UserInfoControllerImpl(Context context) { mContext = context; IntentFilter filter = new IntentFilter(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 15b2f2bcb755..9343bf12cc7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; import android.app.ActivityManager; import android.app.Dialog; @@ -50,7 +51,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.UserIcons; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.Utils; -import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.GuestResumeSessionReceiver; import com.android.systemui.Prefs; @@ -68,9 +68,14 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + /** * Keeps a list of all users on the device for user switching. */ +@Singleton public class UserSwitcherController implements Dumpable { private static final String TAG = "UserSwitcherController"; @@ -102,8 +107,9 @@ public class UserSwitcherController implements Dumpable { private Intent mSecondaryUserServiceIntent; private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); + @Inject public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor, - Handler handler, ActivityStarter activityStarter) { + @Named(MAIN_HANDLER_NAME) Handler handler, ActivityStarter activityStarter) { mContext = context; mGuestResumeSessionReceiver.register(context); mKeyguardMonitor = keyguardMonitor; @@ -590,7 +596,7 @@ public class UserSwitcherController implements Dumpable { protected BaseUserAdapter(UserSwitcherController controller) { mController = controller; - mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); + mKeyguardMonitor = controller.mKeyguardMonitor; controller.addAdapter(new WeakReference<>(this)); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java index 693df884690a..6f63544d3cfa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java @@ -53,7 +53,9 @@ public class WifiSignalController extends connectivityManager, this::handleStatusUpdated); mWifiTracker.setListening(true); mHasMobileData = hasMobileData; - wifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback(), null); + if (wifiManager != null) { + wifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback(), null); + } // WiFi only has one state. mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup( "Wi-Fi Icons", diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java index 89ccff03133d..29c42d24b3b4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.policy; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + import android.app.ActivityManager; import android.app.AlarmManager; import android.app.NotificationManager; @@ -48,7 +50,12 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Objects; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + /** Platform implementation of the zen mode controller. **/ +@Singleton public class ZenModeControllerImpl extends CurrentUserTracker implements ZenModeController, Dumpable { private static final String TAG = "ZenModeController"; @@ -71,7 +78,8 @@ public class ZenModeControllerImpl extends CurrentUserTracker private long mZenUpdateTime; private NotificationManager.Policy mConsolidatedNotificationPolicy; - public ZenModeControllerImpl(Context context, Handler handler) { + @Inject + public ZenModeControllerImpl(Context context, @Named(MAIN_HANDLER_NAME) Handler handler) { super(context); mContext = context; mModeSetting = new GlobalSetting(mContext, handler, Global.ZEN_MODE) { @@ -109,8 +117,8 @@ public class ZenModeControllerImpl extends CurrentUserTracker @Override public boolean areNotificationsHiddenInShade() { if (mZenMode != Global.ZEN_MODE_OFF) { - return (mConfig.suppressedVisualEffects & NotificationManager.Policy - .SUPPRESSED_EFFECT_NOTIFICATION_LIST) != 0; + return (mConsolidatedNotificationPolicy.suppressedVisualEffects + & NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST) != 0; } return false; } @@ -252,7 +260,6 @@ public class ZenModeControllerImpl extends CurrentUserTracker } } - @VisibleForTesting protected void updateZenModeConfig() { final ZenModeConfig config = mNoMan.getZenModeConfig(); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java index e85dee841715..8f3a8f6ec960 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java @@ -21,6 +21,9 @@ import android.view.WindowManager; import com.android.systemui.Dependency; import com.android.systemui.tuner.TunerService.Tunable; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Version of Space that can be resized by a tunable setting. */ @@ -35,8 +38,9 @@ public class TunablePadding implements Tunable { private final View mView; private final int mDefaultSize; private final float mDensity; + private final TunerService mTunerService; - private TunablePadding(String key, int def, int flags, View view) { + private TunablePadding(String key, int def, int flags, View view, TunerService tunerService) { mDefaultSize = def; mFlags = flags; mView = view; @@ -44,7 +48,8 @@ public class TunablePadding implements Tunable { view.getContext().getSystemService(WindowManager.class) .getDefaultDisplay().getMetrics(metrics); mDensity = metrics.density; - Dependency.get(TunerService.class).addTunable(this, key); + mTunerService = tunerService; + mTunerService.addTunable(this, key); } @Override @@ -66,16 +71,29 @@ public class TunablePadding implements Tunable { } public void destroy() { - Dependency.get(TunerService.class).removeTunable(this); + mTunerService.removeTunable(this); } - // Exists for easy injecting in tests. + /** + * Exists for easy injecting in tests. + */ + @Singleton public static class TunablePaddingService { + + private final TunerService mTunerService; + + /** + */ + @Inject + public TunablePaddingService(TunerService tunerService) { + mTunerService = tunerService; + } + public TunablePadding add(View view, String key, int defaultSize, int flags) { if (view == null) { throw new IllegalArgumentException(); } - return new TunablePadding(key, defaultSize, flags, view); + return new TunablePadding(key, defaultSize, flags, view, mTunerService); } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index 196d9bc32e75..6185063e7966 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -15,6 +15,8 @@ */ package com.android.systemui.tuner; +import static com.android.systemui.Dependency.BG_HANDLER_NAME; + import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; @@ -33,7 +35,6 @@ import android.util.ArraySet; import com.android.internal.util.ArrayUtils; import com.android.systemui.DemoMode; -import com.android.systemui.Dependency; import com.android.systemui.qs.QSTileHost; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.phone.StatusBarIconController; @@ -43,7 +44,14 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Set; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +/** + */ +@Singleton public class TunerServiceImpl extends TunerService { private static final String TUNER_VERSION = "sysui_tuner_version"; @@ -65,19 +73,25 @@ public class TunerServiceImpl extends TunerService { // Set of all tunables, used for leak detection. private final HashSet<Tunable> mTunables = LeakDetector.ENABLED ? new HashSet<>() : null; private final Context mContext; + private final LeakDetector mLeakDetector; private ContentResolver mContentResolver; private int mCurrentUser; private CurrentUserTracker mUserTracker; - public TunerServiceImpl(Context context) { + /** + */ + @Inject + public TunerServiceImpl(Context context, @Named(BG_HANDLER_NAME) Handler bgHandler, + LeakDetector leakDetector) { mContext = context; mContentResolver = mContext.getContentResolver(); + mLeakDetector = leakDetector; for (UserInfo user : UserManager.get(mContext).getUsers()) { mCurrentUser = user.getUserHandle().getIdentifier(); if (getValue(TUNER_VERSION, 0) != CURRENT_TUNER_VERSION) { - upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION); + upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION, bgHandler); } } @@ -98,7 +112,7 @@ public class TunerServiceImpl extends TunerService { mUserTracker.stopTracking(); } - private void upgradeTuner(int oldVersion, int newVersion) { + private void upgradeTuner(int oldVersion, int newVersion, Handler bgHandler) { if (oldVersion < 1) { String blacklistStr = getValue(StatusBarIconController.ICON_BLACKLIST); if (blacklistStr != null) { @@ -120,7 +134,7 @@ public class TunerServiceImpl extends TunerService { if (oldVersion < 4) { // Delay this so that we can wait for everything to be registered first. final int user = mCurrentUser; - new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed( + bgHandler.postDelayed( () -> clearAllFromUser(user), 5000); } setValue(TUNER_VERSION, newVersion); @@ -167,7 +181,7 @@ public class TunerServiceImpl extends TunerService { mTunableLookup.get(key).add(tunable); if (LeakDetector.ENABLED) { mTunables.add(tunable); - Dependency.get(LeakDetector.class).trackCollection(mTunables, "TunerService.mTunables"); + mLeakDetector.trackCollection(mTunables, "TunerService.mTunables"); } Uri uri = Settings.Secure.getUriFor(key); if (!mListeningUris.containsKey(uri)) { diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java index 88cbbb574aff..31f4991a82b5 100644 --- a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java +++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java @@ -38,6 +38,9 @@ import com.android.systemui.shared.plugins.PluginManager; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Wrapper around sensor manager that hides potential sources of latency. * @@ -45,6 +48,7 @@ import java.util.List; * without blocking. Note that this means registering listeners now always appears successful even * if it is not. */ +@Singleton public class AsyncSensorManager extends SensorManager implements PluginListener<SensorManagerPlugin> { @@ -56,8 +60,14 @@ public class AsyncSensorManager extends SensorManager @VisibleForTesting final Handler mHandler; private final List<SensorManagerPlugin> mPlugins; - public AsyncSensorManager(SensorManager inner, PluginManager pluginManager) { - mInner = inner; + @Inject + public AsyncSensorManager(Context context, PluginManager pluginManager) { + this(context.getSystemService(SensorManager.class), pluginManager); + } + + @VisibleForTesting + AsyncSensorManager(SensorManager sensorManager, PluginManager pluginManager) { + mInner = sensorManager; mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL); diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java index e458e6376580..59aa52242f88 100644 --- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java @@ -24,6 +24,7 @@ import android.view.LayoutInflater; import android.view.View; import com.android.systemui.SystemUIFactory; +import com.android.systemui.qs.QSFooterImpl; import com.android.systemui.qs.QuickStatusBarHeader; import java.lang.reflect.InvocationTargetException; @@ -107,6 +108,10 @@ public class InjectionInflationController { * Creates the QuickStatusBarHeader. */ QuickStatusBarHeader createQsHeader(); + /** + * Creates the QSFooterImpl. + */ + QSFooterImpl createQsFooter(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java index b2cc2694916e..b590e7738f08 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java @@ -17,6 +17,7 @@ package com.android.systemui.util.leak; import static com.android.internal.logging.MetricsLogger.VIEW_UNKNOWN; +import static com.android.systemui.Dependency.BG_LOOPER_NAME; import android.app.ActivityManager; import android.content.Context; @@ -42,15 +43,22 @@ import android.text.format.DateUtils; import android.util.Log; import android.util.LongSparseArray; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SystemUI; +import com.android.systemui.SystemUIFactory; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +/** + */ +@Singleton public class GarbageMonitor { private static final boolean LEAK_REPORTING_ENABLED = Build.IS_DEBUGGABLE @@ -85,9 +93,12 @@ public class GarbageMonitor { private long mHeapLimit; + /** + */ + @Inject public GarbageMonitor( Context context, - Looper bgLooper, + @Named(BG_LOOPER_NAME) Looper bgLooper, LeakDetector leakDetector, LeakReporter leakReporter) { mContext = context.getApplicationContext(); @@ -335,9 +346,10 @@ public class GarbageMonitor { private final GarbageMonitor gm; private ProcessMemInfo pmi; + @Inject public MemoryTile(QSHost host) { super(host); - gm = Dependency.get(GarbageMonitor.class); + gm = SystemUIFactory.getInstance().getRootComponent().createGarbageMonitor(); } @Override @@ -442,7 +454,8 @@ public class GarbageMonitor { Settings.Secure.getInt( mContext.getContentResolver(), FORCE_ENABLE_LEAK_REPORTING, 0) != 0; - mGarbageMonitor = Dependency.get(GarbageMonitor.class); + mGarbageMonitor = SystemUIFactory.getInstance().getRootComponent() + .createGarbageMonitor(); if (LEAK_REPORTING_ENABLED || forceEnable) { mGarbageMonitor.startLeakMonitor(); } diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java index a47e99d1e84d..b25df5f9c07f 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java @@ -16,6 +16,9 @@ package com.android.systemui.util.leak; +import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME; + +import android.annotation.Nullable; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -39,9 +42,14 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + /** * Dumps data to debug leaks and posts a notification to share the data. */ +@Singleton public class LeakReporter { static final String TAG = "LeakReporter"; @@ -56,7 +64,9 @@ public class LeakReporter { private final LeakDetector mLeakDetector; private final String mLeakReportEmail; - public LeakReporter(Context context, LeakDetector leakDetector, String leakReportEmail) { + @Inject + public LeakReporter(Context context, LeakDetector leakDetector, + @Nullable @Named(LEAK_REPORT_EMAIL_NAME) String leakReportEmail) { mContext = context; mLeakDetector = leakDetector; mLeakReportEmail = leakReportEmail; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index e20e267336ea..32bc01cdfdfe 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -67,6 +67,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Source of truth for all state / events related to the volume dialog. No presentation. * @@ -74,6 +77,7 @@ import java.util.Objects; * * Methods ending in "W" must be called on the worker thread. */ +@Singleton public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpable { private static final String TAG = Util.logTag(VolumeDialogControllerImpl.class); @@ -131,6 +135,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa protected final VC mVolumeController = new VC(); + @Inject public VolumeDialogControllerImpl(Context context) { mContext = context.getApplicationContext(); mNotificationManager = (NotificationManager) mContext.getSystemService( @@ -545,7 +550,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } private boolean updateZenConfig() { - final NotificationManager.Policy policy = mNotificationManager.getNotificationPolicy(); + final NotificationManager.Policy policy = + mNotificationManager.getConsolidatedNotificationPolicy(); boolean disallowAlarms = (policy.priorityCategories & NotificationManager.Policy .PRIORITY_CATEGORY_ALARMS) == 0; boolean disallowMedia = (policy.priorityCategories & NotificationManager.Policy diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index b84f85bdbc4c..122b094558ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -16,13 +16,13 @@ package com.android.systemui; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; -import static com.android.systemui.ScreenDecorations.rectsToRegion; +import static com.android.systemui.ScreenDecorations.rectsToRegion; import static com.android.systemui.tuner.TunablePadding.FLAG_END; import static com.android.systemui.tuner.TunablePadding.FLAG_START; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -87,7 +87,6 @@ public class ScreenDecorationsTest extends SysuiTestCase { mWindowManager = mock(WindowManager.class); mView = spy(new StatusBarWindowView(mContext, null)); when(mStatusBar.getStatusBarWindow()).thenReturn(mView); - when(mStatusBar.getNavigationBarWindow()).thenReturn(mView); mContext.putComponent(StatusBar.class, mStatusBar); Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay(); 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 16ef63f1848a..8f2b2d065f72 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -144,8 +144,7 @@ public class BubbleControllerTest extends SysuiTestCase { TestableBubbleController(Context context, StatusBarWindowController statusBarWindowController) { - super(context); - mStatusBarWindowController = statusBarWindowController; + super(context, statusBarWindowController); } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java b/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java new file mode 100644 index 000000000000..b368876d2ae7 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java @@ -0,0 +1,38 @@ +/* + * 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.dock; + +/** + * A rudimentary fake for DockManager. + */ +public class DockManagerFake implements DockManager { + DockEventListener mCallback; + + @Override + public void addListener(DockEventListener callback) { + this.mCallback = callback; + } + + @Override + public void removeListener(DockEventListener callback) { + this.mCallback = null; + } + + public void setDockEvent(int event) { + mCallback.onEvent(event); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java new file mode 100644 index 000000000000..926ff69651be --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java @@ -0,0 +1,204 @@ +/* + * 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.doze; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Instrumentation; +import android.os.Handler; +import android.os.Looper; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.dock.DockManager; +import com.android.systemui.dock.DockManagerFake; +import com.android.systemui.doze.DozeMachine.State; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class DozeDockHandlerTest extends SysuiTestCase { + private DozeDockHandler mDockHandler; + private DozeMachine mMachine; + private DozeHostFake mHost; + private AmbientDisplayConfiguration mConfig; + private Instrumentation mInstrumentation; + private DockManagerFake mDockManagerFake; + + @BeforeClass + public static void setupSuite() { + // We can't use KeyguardUpdateMonitor from tests. + DozeLog.setRegisterKeyguardCallback(false); + } + + @Before + public void setUp() throws Exception { + mInstrumentation = InstrumentationRegistry.getInstrumentation(); + mMachine = mock(DozeMachine.class); + mHost = spy(new DozeHostFake()); + mConfig = DozeConfigurationUtil.createMockConfig(); + doReturn(false).when(mConfig).alwaysOnEnabled(anyInt()); + + mDockManagerFake = spy(new DockManagerFake()); + mContext.putComponent(DockManager.class, mDockManagerFake); + + mDockHandler = new DozeDockHandler(mContext, mMachine, mHost, mConfig, + Handler.createAsync(Looper.myLooper())); + } + + @Test + public void testDockEventListener_registerAndUnregister() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + + verify(mDockManagerFake).addListener(any()); + + mDockHandler.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH); + + verify(mDockManagerFake).removeListener(any()); + } + + @Test + public void testOnEvent_dockedWhenDoze_requestPulse() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE); + + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED); + + verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING)); + } + + @Test + public void testOnEvent_dockedWhenDozeAoD_requestPulse() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_AOD); + + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED); + + verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING)); + } + + @Test + public void testOnEvent_dockedHideWhenPulsing_requestPulseOut() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(State.DOZE_PULSING); + when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_DOCKING); + + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED_HIDE); + + verify(mHost).stopPulsing(); + } + + @Test + public void testOnEvent_undockedWhenPulsing_requestPulseOut() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_PULSING); + when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_DOCKING); + + mDockManagerFake.setDockEvent(DockManager.STATE_NONE); + + verify(mHost).stopPulsing(); + } + + @Test + public void testOnEvent_undockedWhenDoze_neverRequestPulseOut() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE); + + mDockManagerFake.setDockEvent(DockManager.STATE_NONE); + + verify(mHost, never()).stopPulsing(); + } + + @Test + public void testOnEvent_undockedWhenDozeAndEnabledAoD_requestDozeAoD() { + doReturn(true).when(mConfig).alwaysOnEnabled(anyInt()); + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE); + + mDockManagerFake.setDockEvent(DockManager.STATE_NONE); + + verify(mMachine).requestState(eq(State.DOZE_AOD)); + } + + @Test + public void testTransitionToDoze_whenDocked_requestPulse() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.INITIALIZED); + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE); + mDockHandler.transitionTo(State.INITIALIZED, DozeMachine.State.DOZE); + + TestableLooper.get(this).processAllMessages(); + + verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING)); + } + + @Test + public void testTransitionToDozeAoD_whenDocked_requestPulse() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.INITIALIZED); + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_AOD); + mDockHandler.transitionTo(State.INITIALIZED, DozeMachine.State.DOZE_AOD); + + TestableLooper.get(this).processAllMessages(); + + verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING)); + } + + @Test + public void testTransitionToDoze_whenDockedHide_neverRequestPulse() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.INITIALIZED); + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED_HIDE); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE); + + mDockHandler.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE); + + verify(mMachine, never()).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING)); + } + + @Test + public void testTransitionToDozeAoD_whenDockedHide_requestDoze() { + mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); + when(mMachine.getState()).thenReturn(DozeMachine.State.INITIALIZED); + mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED_HIDE); + when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_AOD); + + mDockHandler.transitionTo(DozeMachine.State.INITIALIZED, State.DOZE_AOD); + + verify(mMachine).requestState(eq(State.DOZE)); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java index 6abd407afd91..ce28b50436eb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java @@ -17,9 +17,6 @@ package com.android.systemui.doze; import android.annotation.NonNull; -import android.app.PendingIntent; - -import com.android.systemui.util.wakelock.WakeLock; /** * A rudimentary fake for DozeHost. @@ -85,11 +82,6 @@ class DozeHostFake implements DozeHost { } @Override - public void startPendingIntentDismissingKeyguard(PendingIntent intent) { - throw new RuntimeException("not implemented"); - } - - @Override public void onIgnoreTouchWhilePulsing(boolean ignore) { } @@ -99,6 +91,9 @@ class DozeHostFake implements DozeHost { } @Override + public void stopPulsing() {} + + @Override public void setAnimateWakeup(boolean animateWakeup) { this.animateWakeup = animateWakeup; } @@ -115,11 +110,6 @@ class DozeHostFake implements DozeHost { } @Override - public void setPassiveInterrupt(boolean lightInterrupt) { - - } - - @Override public void setDozeScreenBrightness(int value) { } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/LockScreenWakeUpControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/LockScreenWakeUpControllerTest.java deleted file mode 100644 index 8963b5930d50..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/LockScreenWakeUpControllerTest.java +++ /dev/null @@ -1,142 +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.doze; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.os.Handler; -import android.os.PowerManager; -import android.support.test.filters.SmallTest; - -import com.android.internal.hardware.AmbientDisplayConfiguration; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.SensorManagerPlugin; -import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.util.AsyncSensorManager; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(JUnit4.class) -@SmallTest -public class LockScreenWakeUpControllerTest extends SysuiTestCase { - - @Mock - private AsyncSensorManager mAsyncSensorManager; - @Mock - private SensorManagerPlugin.Sensor mSensor; - @Mock - private AmbientDisplayConfiguration mAmbientDisplayConfiguration; - @Mock - private PowerManager mPowerManager; - @Mock - private DozeHost mDozeHost; - @Mock - private StatusBarStateController mStatusBarStateController; - @Mock - private Handler mHandler; - - private LockScreenWakeUpController mLockScreenWakeUpController; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - doAnswer(invocation -> { - ((Runnable) invocation.getArgument(0)).run(); - return null; - }).when(mHandler).post(any()); - - mLockScreenWakeUpController = new LockScreenWakeUpController(mAsyncSensorManager, mSensor, - mAmbientDisplayConfiguration, mPowerManager, mDozeHost, mStatusBarStateController, - mHandler); - } - - @Test - public void testOnStateChanged_registersUnregistersListener() { - when(mAmbientDisplayConfiguration.wakeLockScreenGestureEnabled(anyInt())).thenReturn(true); - mLockScreenWakeUpController.onStateChanged(StatusBarState.KEYGUARD); - mLockScreenWakeUpController.onStateChanged(StatusBarState.SHADE); - - verify(mAsyncSensorManager, times(1)).registerPluginListener(eq(mSensor), - eq(mLockScreenWakeUpController)); - - mLockScreenWakeUpController.onStateChanged(StatusBarState.SHADE); - verify(mAsyncSensorManager).unregisterPluginListener(eq(mSensor), - eq(mLockScreenWakeUpController)); - } - - @Test - public void testOnStateChanged_disabledSensor() { - when(mAmbientDisplayConfiguration.wakeLockScreenGestureEnabled(anyInt())) - .thenReturn(false); - mLockScreenWakeUpController.onStateChanged(StatusBarState.KEYGUARD); - mLockScreenWakeUpController.onStateChanged(StatusBarState.SHADE); - - verify(mAsyncSensorManager, never()).registerPluginListener(eq(mSensor), - eq(mLockScreenWakeUpController)); - } - - @Test - public void testOnSensorChanged_postsToMainThread() { - SensorManagerPlugin.SensorEvent event = new SensorManagerPlugin.SensorEvent(mSensor, 0); - mLockScreenWakeUpController.onSensorChanged(event); - - verify(mHandler).post(any()); - } - - @Test - public void testOnSensorChanged_wakeUpWhenDozing() { - SensorManagerPlugin.SensorEvent event = - new SensorManagerPlugin.SensorEvent(mSensor, 0, new float[] {1}); - mLockScreenWakeUpController.onSensorChanged(event); - verify(mPowerManager, never()).wakeUp(anyLong(), any()); - - mLockScreenWakeUpController.onDozingChanged(true); - mLockScreenWakeUpController.onSensorChanged(event); - verify(mPowerManager).wakeUp(anyLong(), any()); - } - - @Test - public void testOnSensorChanged_sleepsWhenAwake() { - boolean[] goToSleep = new boolean[] {false}; - doAnswer(invocation -> goToSleep[0] = true) - .when(mPowerManager).goToSleep(anyLong(), anyInt(), anyInt()); - SensorManagerPlugin.SensorEvent event = - new SensorManagerPlugin.SensorEvent(mSensor, 0, new float[] {0}); - mLockScreenWakeUpController.onDozingChanged(true); - mLockScreenWakeUpController.onSensorChanged(event); - Assert.assertFalse("goToSleep should have never been called.", goToSleep[0]); - - mLockScreenWakeUpController.onDozingChanged(false); - mLockScreenWakeUpController.onSensorChanged(event); - Assert.assertTrue("goToSleep should have been called.", goToSleep[0]); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java index 7d94635ab548..a8ff0b21bab9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify; import android.app.AlarmManager; import android.content.ContentResolver; +import android.media.MediaMetadata; import android.net.Uri; import android.provider.Settings; import android.support.test.filters.SmallTest; @@ -42,6 +43,7 @@ import androidx.slice.core.SliceQuery; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.NotificationMediaManager; import org.junit.Assert; import org.junit.Before; @@ -63,6 +65,8 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { private ContentResolver mContentResolver; @Mock private AlarmManager mAlarmManager; + @Mock + private NotificationMediaManager mNotificationMediaManager; private TestableKeyguardSliceProvider mProvider; private boolean mIsZenMode; @@ -72,6 +76,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { mIsZenMode = false; mProvider = new TestableKeyguardSliceProvider(); mProvider.attachInfo(getContext(), null); + mProvider.initDependencies(); SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST))); } @@ -91,6 +96,16 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { } @Test + public void onBindSlice_readsMedia() { + MediaMetadata metadata = mock(MediaMetadata.class); + mProvider.onMetadataChanged(metadata); + mProvider.onBindSlice(mProvider.getUri()); + verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_TITLE)); + verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_ARTIST)); + verify(mNotificationMediaManager).getMediaIcon(); + } + + @Test public void cleansDateFormat() { mProvider.mKeyguardUpdateMonitorCallback.onTimeZoneChanged(null); TestableLooper.get(this).processAllMessages(); @@ -136,14 +151,20 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { public void addZenMode_addedToSlice() { ListBuilder listBuilder = spy(new ListBuilder(getContext(), mProvider.getUri(), ListBuilder.INFINITY)); - mProvider.addZenMode(listBuilder); + mProvider.addZenModeLocked(listBuilder); verify(listBuilder, never()).addRow(any(ListBuilder.RowBuilder.class)); mIsZenMode = true; - mProvider.addZenMode(listBuilder); + mProvider.addZenModeLocked(listBuilder); verify(listBuilder).addRow(any(ListBuilder.RowBuilder.class)); } + @Test + public void onMetadataChanged_updatesSlice() { + mProvider.onMetadataChanged(mock(MediaMetadata.class)); + verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null)); + } + private class TestableKeyguardSliceProvider extends KeyguardSliceProvider { int mCleanDateFormatInvokations; private int mCounter; @@ -166,8 +187,8 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { } @Override - void cleanDateFormat() { - super.cleanDateFormat(); + void cleanDateFormatLocked() { + super.cleanDateFormatLocked(); mCleanDateFormatInvokations++; } @@ -177,8 +198,13 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { } @Override - protected String getFormattedDate() { - return super.getFormattedDate() + mCounter++; + protected String getFormattedDateLocked() { + return super.getFormattedDateLocked() + mCounter++; + } + + @Override + public void initDependencies() { + mMediaManager = mNotificationMediaManager; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt index b23f667e4388..d3b3dae2c1cd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt @@ -51,4 +51,19 @@ class PrivacyDialogBuilderTest : SysuiTestCase() { assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1]) assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[2]) } + + @Test + fun testOrder() { + // We want location to always go last, so it will go in the "+ other apps" + val appCamera = PrivacyItem(PrivacyType.TYPE_CAMERA, PrivacyApplication("Camera", context)) + val appMicrophone = + PrivacyItem(PrivacyType.TYPE_MICROPHONE, PrivacyApplication("Microphone", context)) + val appLocation = + PrivacyItem(PrivacyType.TYPE_LOCATION, PrivacyApplication("Location", context)) + + val items = listOf(appLocation, appMicrophone, appCamera) + val textBuilder = PrivacyDialogBuilder(context, items) + val appList = textBuilder.appsAndTypes.map { it.first }.map { it.packageName } + assertEquals(listOf("Camera", "Microphone", "Location"), appList) + } }
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index ab508a25e76b..2cb326eb7269 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import android.app.Fragment; import android.content.Context; import android.os.Bundle; +import android.os.Handler; import android.os.Looper; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; @@ -36,10 +37,14 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiBaseFragmentTest; +import com.android.systemui.qs.tileimpl.QSFactoryImpl; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.Clock; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.statusbar.policy.UserSwitcherController; +import com.android.systemui.tuner.TunerService; import com.android.systemui.util.InjectionInflationController; import org.junit.Before; @@ -85,7 +90,9 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { QSFragment qs = (QSFragment) mFragment; mFragments.dispatchResume(); processAllMessages(); - QSTileHost host = new QSTileHost(mContext, null, mock(StatusBarIconController.class)); + QSTileHost host = new QSTileHost(mContext, mock(StatusBarIconController.class), + mock(QSFactoryImpl.class), new Handler(), Looper.myLooper(), + mock(PluginManager.class), mock(TunerService.class)); qs.setHost(host); qs.setListening(true); @@ -124,7 +131,10 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { @Override protected Fragment instantiate(Context context, String className, Bundle arguments) { - return new QSFragment(new RemoteInputQuickSettingsDisabler(context), - new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent())); + return new QSFragment( + new RemoteInputQuickSettingsDisabler(context, mock(ConfigurationController.class)), + new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()), + context, + mock(QSTileHost.class)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java index c6597b9bd534..63f4bbc73ed8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java @@ -21,6 +21,7 @@ import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.content.ComponentName; +import android.os.Handler; import android.os.Looper; import android.service.quicksettings.Tile; import android.test.suitebuilder.annotation.SmallTest; @@ -30,8 +31,11 @@ import android.testing.TestableLooper.RunWithLooper; import com.android.systemui.SysuiTestCase; import com.android.systemui.qs.QSTileHost; +import com.android.systemui.qs.tileimpl.QSFactoryImpl; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.BluetoothController; +import com.android.systemui.tuner.TunerService; import org.junit.After; import org.junit.Before; @@ -55,8 +59,13 @@ public class TileServicesTest extends SysuiTestCase { public void setUp() throws Exception { mDependency.injectMockDependency(BluetoothController.class); mManagers = new ArrayList<>(); - QSTileHost host = new QSTileHost(mContext, null, - mock(StatusBarIconController.class)); + QSTileHost host = new QSTileHost(mContext, + mock(StatusBarIconController.class), + mock(QSFactoryImpl.class), + new Handler(), + Looper.myLooper(), + mock(PluginManager.class), + mock(TunerService.class)); mTileService = new TestTileServices(host, Looper.getMainLooper()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java index d9412ecd9a3a..efcbb769cbf0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java @@ -15,8 +15,8 @@ package com.android.systemui.qs.tiles; import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertTrue; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -26,6 +26,8 @@ import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import androidx.lifecycle.LifecycleOwner; + import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; @@ -79,7 +81,8 @@ public class CastTileTest extends SysuiTestCase { when(mHost.getContext()).thenReturn(mContext); - mCastTile = new CastTile(mHost); + mCastTile = new CastTile(mHost, mController, mKeyguard, mNetworkController, + mActivityStarter); // We are not setting the mocks to listening, so we trigger a first refresh state to // set the initial state @@ -88,7 +91,8 @@ public class CastTileTest extends SysuiTestCase { mCastTile.handleSetListening(true); ArgumentCaptor<NetworkController.SignalCallback> signalCallbackArgumentCaptor = ArgumentCaptor.forClass(NetworkController.SignalCallback.class); - verify(mNetworkController).addCallback(signalCallbackArgumentCaptor.capture()); + verify(mNetworkController).observe(any(LifecycleOwner.class), + signalCallbackArgumentCaptor.capture()); mCallback = signalCallbackArgumentCaptor.getValue(); } 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 index 90792e3d958f..751a616eee32 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/SensorPrivacyTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/SensorPrivacyTileTest.java @@ -16,6 +16,7 @@ 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; @@ -27,6 +28,7 @@ import android.testing.TestableLooper; 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; @@ -64,7 +66,8 @@ public class SensorPrivacyTileTest extends SysuiTestCase { when(mHost.getContext()).thenReturn(mContext); - mSensorPrivacyTile = new SensorPrivacyTile(mHost); + mSensorPrivacyTile = new SensorPrivacyTile(mHost, mSensorPrivacyManager, mKeyguard, + mock(ActivityStarter.class)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java index 894ef3dde779..425ca581493e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java @@ -57,7 +57,7 @@ public class NonPhoneDependencyTest extends SysuiTestCase { @Mock private NotificationPresenter mPresenter; @Mock private NotificationListContainer mListContainer; @Mock - private NotificationEntryListener mEntryManagerCallback; + private NotificationEntryListener mEntryListener; @Mock private HeadsUpManager mHeadsUpManager; @Mock private RemoteInputController.Delegate mDelegate; @Mock private NotificationRemoteInputManager.Callback mRemoteInputManagerCallback; @@ -87,8 +87,8 @@ public class NonPhoneDependencyTest extends SysuiTestCase { NotificationViewHierarchyManager viewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class); Dependency.get(InitController.class).executePostInitTasks(); - entryManager.setUpWithPresenter(mPresenter, mListContainer, mEntryManagerCallback, - mHeadsUpManager); + entryManager.setUpWithPresenter(mPresenter, mListContainer, mHeadsUpManager); + entryManager.addNotificationEntryListener(mEntryListener); gutsManager.setUpWithPresenter(mPresenter, mListContainer, mCheckSaveListener, mOnSettingsClickListener); notificationLogger.setUpWithContainer(mListContainer); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java index bee931f0f8e8..150dcb9f841c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java @@ -20,7 +20,6 @@ import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; -import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputActiveExtender; import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputHistoryExtender; @@ -28,6 +27,7 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager.SmartReplyH import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.phone.ShadeController; import com.google.android.collect.Sets; @@ -37,6 +37,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import dagger.Lazy; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @@ -66,14 +68,11 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); - mDependency.injectTestDependency(NotificationLockscreenUserManager.class, - mLockscreenUserManager); - mDependency.injectTestDependency(SmartReplyController.class, mSmartReplyController); - mDependency.injectTestDependency(Dependency.MAIN_HANDLER, - Handler.createAsync(Looper.myLooper())); - mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext); + mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext, + mLockscreenUserManager, mSmartReplyController, mEntryManager, + () -> mock(ShadeController.class), + Handler.createAsync(Looper.myLooper())); mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0, new Notification(), UserHandle.CURRENT, null, 0); mEntry = new NotificationData.Entry(mSbn); @@ -90,7 +89,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { @Test public void testPerformOnRemoveNotification() { when(mController.isRemoteInputActive(mEntry)).thenReturn(true); - mRemoteInputManager.onPerformRemoveNotification(mSbn, mEntry); + mRemoteInputManager.onPerformRemoveNotification(mEntry, mSbn.getKey()); verify(mController).removeRemoteInput(mEntry, null); } @@ -196,8 +195,15 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { private class TestableNotificationRemoteInputManager extends NotificationRemoteInputManager { - public TestableNotificationRemoteInputManager(Context context) { - super(context); + + TestableNotificationRemoteInputManager(Context context, + NotificationLockscreenUserManager lockscreenUserManager, + SmartReplyController smartReplyController, + NotificationEntryManager notificationEntryManager, + Lazy<ShadeController> shadeController, + Handler mainHandler) { + super(context, lockscreenUserManager, smartReplyController, notificationEntryManager, + shadeController, mainHandler); } public void setUpWithPresenterForTest(Callback callback, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index 520a927d1ab0..8cf4b05b6371 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -20,6 +20,7 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -35,6 +36,7 @@ import android.widget.LinearLayout; import com.android.systemui.Dependency; import com.android.systemui.InitController; import com.android.systemui.SysuiTestCase; +import com.android.systemui.bubbles.BubbleController; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationData.Entry; @@ -90,7 +92,10 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); - mViewHierarchyManager = new NotificationViewHierarchyManager(mContext); + mViewHierarchyManager = new NotificationViewHierarchyManager(mContext, + mLockscreenUserManager, mGroupManager, mVisualStabilityManager, + mock(StatusBarStateController.class), mEntryManager, mock(BubbleController.class), + () -> mShadeController); Dependency.get(InitController.class).executePostInitTasks(); mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java index 14e611a26b4c..e7a1f051a6df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java @@ -19,10 +19,13 @@ import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.app.ActivityManager; import android.app.Notification; +import android.os.Handler; +import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.service.notification.StatusBarNotification; @@ -35,6 +38,7 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.phone.ShadeController; import org.junit.Before; import org.junit.Test; @@ -70,13 +74,16 @@ public class SmartReplyControllerTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager); - mDependency.injectTestDependency(IStatusBarService.class, mIStatusBarService); - mSmartReplyController = new SmartReplyController(); + mSmartReplyController = new SmartReplyController(mNotificationEntryManager, + mIStatusBarService); mDependency.injectTestDependency(SmartReplyController.class, mSmartReplyController); - mRemoteInputManager = new NotificationRemoteInputManager(mContext); + mRemoteInputManager = new NotificationRemoteInputManager(mContext, + mock(NotificationLockscreenUserManager.class), mSmartReplyController, + mNotificationEntryManager, () -> mock(ShadeController.class), + Handler.createAsync(Looper.myLooper())); mRemoteInputManager.setUpWithCallback(mCallback, mDelegate); mNotification = new Notification.Builder(mContext, "") .setSmallIcon(R.drawable.ic_person) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java index 701ea7d3e2fe..a2d408e4e97e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java @@ -52,7 +52,6 @@ import android.util.ArraySet; import android.widget.FrameLayout; import com.android.internal.logging.MetricsLogger; -import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.Dependency; import com.android.systemui.ForegroundServiceController; import com.android.systemui.InitController; @@ -61,7 +60,6 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.RemoteInputController; @@ -104,13 +102,12 @@ public class NotificationEntryManagerTest extends SysuiTestCase { @Mock private ExpandableNotificationRow mRow; @Mock private NotificationListContainer mListContainer; @Mock - private NotificationEntryListener mCallback; + private NotificationEntryListener mEntryListener; @Mock private NotificationRowBinder.BindRowCallback mBindCallback; @Mock private HeadsUpManager mHeadsUpManager; @Mock private NotificationListenerService.RankingMap mRankingMap; @Mock private RemoteInputController mRemoteInputController; - @Mock private IStatusBarService mBarService; // Dependency mocks: @Mock private ForegroundServiceController mForegroundServiceController; @@ -118,7 +115,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase { @Mock private NotificationGroupManager mGroupManager; @Mock private NotificationGutsManager mGutsManager; @Mock private NotificationRemoteInputManager mRemoteInputManager; - @Mock private NotificationMediaManager mMediaManager; @Mock private NotificationListener mNotificationListener; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private VisualStabilityManager mVisualStabilityManager; @@ -134,9 +130,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase { private class TestableNotificationEntryManager extends NotificationEntryManager { private final CountDownLatch mCountDownLatch; - public TestableNotificationEntryManager(Context context, IStatusBarService barService) { + TestableNotificationEntryManager(Context context) { super(context); - mBarService = barService; mCountDownLatch = new CountDownLatch(1); } @@ -204,7 +199,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase { mDependency.injectTestDependency(NotificationGroupManager.class, mGroupManager); mDependency.injectTestDependency(NotificationGutsManager.class, mGutsManager); mDependency.injectTestDependency(NotificationRemoteInputManager.class, mRemoteInputManager); - mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager); mDependency.injectTestDependency(NotificationListener.class, mNotificationListener); mDependency.injectTestDependency(DeviceProvisionedController.class, mDeviceProvisionedController); @@ -230,9 +224,10 @@ public class NotificationEntryManagerTest extends SysuiTestCase { mEntry = new NotificationData.Entry(mSbn); mEntry.expandedIcon = mock(StatusBarIconView.class); - mEntryManager = new TestableNotificationEntryManager(mContext, mBarService); + mEntryManager = new TestableNotificationEntryManager(mContext); Dependency.get(InitController.class).executePostInitTasks(); - mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mCallback, mHeadsUpManager); + mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mHeadsUpManager); + mEntryManager.addNotificationEntryListener(mEntryListener); NotificationRowBinder notificationRowBinder = Dependency.get(NotificationRowBinder.class); notificationRowBinder.setUpWithPresenter( @@ -260,8 +255,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { assertTrue(mEntryManager.getCountDownLatch().await(10, TimeUnit.SECONDS)); // Check that no inflation error occurred. - verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(), - any(), anyInt()); + verify(mEntryListener, never()).onInflationError(any(), any()); verify(mForegroundServiceController).addNotification(eq(mSbn), anyInt()); // Row inflation: @@ -272,7 +266,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { verify(mRemoteInputManager).bindRow(entry.getRow()); // Row content inflation: - verify(mCallback).onNotificationAdded(entry); + verify(mEntryListener).onNotificationAdded(entry); verify(mPresenter).updateNotificationViews(); assertEquals(mEntryManager.getNotificationData().get(mSbn.getKey()), entry); @@ -295,12 +289,11 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // Wait for content update. assertTrue(mEntryManager.getCountDownLatch().await(10, TimeUnit.SECONDS)); - verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(), - any(), anyInt()); + verify(mEntryListener, never()).onInflationError(any(), any()); verify(mPresenter).updateNotificationViews(); verify(mForegroundServiceController).updateNotification(eq(mSbn), anyInt()); - verify(mCallback).onNotificationUpdated(mSbn); + verify(mEntryListener).onEntryUpdated(mEntry); assertNotNull(mEntry.getRow()); assertEquals(mEntry.userSentiment, NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE); @@ -315,14 +308,13 @@ public class NotificationEntryManagerTest extends SysuiTestCase { mEntryManager.removeNotification(mSbn.getKey(), mRankingMap); - verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(), - any(), anyInt()); + verify(mEntryListener, never()).onInflationError(any(), any()); - verify(mMediaManager).onNotificationRemoved(mSbn.getKey()); verify(mForegroundServiceController).removeNotification(mSbn); verify(mListContainer).cleanUpViewStateForEntry(mEntry); verify(mPresenter).updateNotificationViews(); - verify(mCallback).onNotificationRemoved(mSbn.getKey(), mSbn); + verify(mEntryListener).onEntryRemoved(mEntry, mSbn.getKey(), mSbn, + null, false /* lifetimeExtended */, false /* removedByUser */); verify(mRow).setRemoved(); assertNull(mEntryManager.getNotificationData().get(mSbn.getKey())); @@ -346,6 +338,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase { assertNotNull(mEntryManager.getNotificationData().get(mSbn.getKey())); verify(extender).setShouldManageLifetime(mEntry, true /* shouldManage */); + verify(mEntryListener).onEntryRemoved(mEntry, mSbn.getKey(), null, + null, true /* lifetimeExtended */, false /* removedByUser */); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java index f19097934fd6..6fbd8c751285 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java @@ -16,28 +16,31 @@ package com.android.systemui.statusbar.notification; +import static junit.framework.Assert.assertEquals; + +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.service.notification.StatusBarNotification; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - @SmallTest @RunWith(AndroidJUnit4.class) public class VisualStabilityManagerTest extends SysuiTestCase { - private VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager(); + private VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager( + mock(NotificationEntryManager.class)); private VisualStabilityManager.Callback mCallback = mock(VisualStabilityManager.Callback.class); private VisibilityLocationProvider mLocationProvider = mock(VisibilityLocationProvider.class); private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class); @@ -45,6 +48,7 @@ public class VisualStabilityManagerTest extends SysuiTestCase { @Before public void setUp() { + mVisualStabilityManager.setUpWithPresenter(mock(NotificationPresenter.class)); mVisualStabilityManager.setVisibilityLocationProvider(mLocationProvider); mEntry = new NotificationData.Entry(mock(StatusBarNotification.class)); mEntry.setRow(mRow); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java index 512acd073a84..7b96518ad13f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.logging; import static org.junit.Assert.assertArrayEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -27,7 +28,6 @@ import static org.mockito.Mockito.when; import android.app.Notification; import android.os.Handler; import android.os.Looper; -import android.os.RemoteException; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.support.test.filters.SmallTest; @@ -36,9 +36,11 @@ import android.testing.TestableLooper; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; +import com.android.systemui.UiOffloadThread; import com.android.systemui.statusbar.NotificationListener; -import com.android.systemui.statusbar.NotificationPresenter; +import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -52,7 +54,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import org.mockito.stubbing.Answer; import java.util.concurrent.ConcurrentLinkedQueue; @@ -63,7 +64,6 @@ public class NotificationLoggerTest extends SysuiTestCase { private static final String TEST_PACKAGE_NAME = "test"; private static final int TEST_UID = 0; - @Mock private NotificationPresenter mPresenter; @Mock private NotificationListContainer mListContainer; @Mock private IStatusBarService mBarService; @Mock private NotificationData mNotificationData; @@ -74,24 +74,25 @@ public class NotificationLoggerTest extends SysuiTestCase { @Mock private NotificationListener mListener; private NotificationData.Entry mEntry; - private StatusBarNotification mSbn; private TestableNotificationLogger mLogger; private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>(); @Before - public void setUp() throws RemoteException { + public void setUp() { MockitoAnnotations.initMocks(this); mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); mDependency.injectTestDependency(NotificationListener.class, mListener); when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); - mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, + StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, + 0, null, TEST_UID, 0, new Notification(), UserHandle.CURRENT, null, 0); - mEntry = new NotificationData.Entry(mSbn); + mEntry = new NotificationData.Entry(sbn); mEntry.setRow(mRow); - mLogger = new TestableNotificationLogger(mBarService); + mLogger = new TestableNotificationLogger(mListener, Dependency.get(UiOffloadThread.class), + mEntryManager, mock(StatusBarStateController.class), mBarService); mLogger.setUpWithContainer(mListContainer); } @@ -101,7 +102,7 @@ public class NotificationLoggerTest extends SysuiTestCase { NotificationVisibility.obtain(mEntry.key, 0, 1, true) }; NotificationVisibility[] noLongerVisibleKeys = {}; - doAnswer((Answer) invocation -> { + doAnswer(invocation -> { try { assertArrayEquals(newlyVisibleKeys, (NotificationVisibility[]) invocation.getArguments()[0]); @@ -153,19 +154,20 @@ public class NotificationLoggerTest extends SysuiTestCase { private class TestableNotificationLogger extends NotificationLogger { - public TestableNotificationLogger(IStatusBarService barService) { + TestableNotificationLogger(NotificationListener notificationListener, + UiOffloadThread uiOffloadThread, + NotificationEntryManager entryManager, + StatusBarStateController statusBarStateController, + IStatusBarService barService) { + super(notificationListener, uiOffloadThread, entryManager, statusBarStateController); mBarService = barService; // Make this on the current thread so we can wait for it during tests. mHandler = Handler.createAsync(Looper.myLooper()); } - public OnChildLocationsChangedListener + OnChildLocationsChangedListener getChildLocationsChangedListenerForTest() { return mNotificationLocationsChangedListener; } - - public Handler getHandlerForTest() { - return mHandler; - } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java index d28f0172e7e0..ecb0cf8ef902 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java @@ -32,6 +32,7 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; @@ -44,6 +45,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.app.INotificationManager; @@ -54,6 +56,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; +import android.metrics.LogMaker; import android.os.IBinder; import android.os.UserHandle; import android.provider.Settings; @@ -69,6 +72,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; @@ -79,6 +83,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -177,6 +182,29 @@ public class NotificationInfoTest extends SysuiTestCase { () -> VISIBLE == mNotificationInfo.findViewById(R.id.prompt).getVisibility()); } + class ImportanceChangeLogMaker implements ArgumentMatcher<LogMaker> { + private static final int CATEGORY = MetricsProto.MetricsEvent.ACTION_SAVE_IMPORTANCE; + private int mType, mSubtype; + + ImportanceChangeLogMaker(int type, int subtype) { + mType = type; + mSubtype = subtype; + } + public boolean matches(LogMaker l) { + return (l.getCategory() == CATEGORY) + && (l.getType() == mType) + && (l.getSubtype() == mSubtype); + } + + public String toString() { + return String.format("LogMaker(%d, %d, %d)", CATEGORY, mType, mSubtype); + } + } + + private LogMaker importanceChangeLog(int type, int subtype) { + return argThat(new ImportanceChangeLogMaker(type, subtype)); + } + @Test public void testBindNotification_SetsTextApplicationName() throws Exception { when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name"); @@ -475,7 +503,7 @@ public class NotificationInfoTest extends SysuiTestCase { TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false, IMPORTANCE_DEFAULT); mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent"); - verify(mMetricsLogger, times(0)).count(anyString(), anyInt()); + verifyZeroInteractions(mMetricsLogger); } @Test @@ -484,7 +512,7 @@ public class NotificationInfoTest extends SysuiTestCase { TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, true, true, true, IMPORTANCE_DEFAULT); mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent"); - verify(mMetricsLogger, times(1)).count(anyString(), anyInt()); + verify(mMetricsLogger).count(eq("HowCanNotifsBeRealIfAppsArent"), eq(1)); } @Test @@ -827,6 +855,9 @@ public class NotificationInfoTest extends SysuiTestCase { waitForUndoButton(); mNotificationInfo.handleCloseControls(true, false); + verify(mMetricsLogger).write(importanceChangeLog( + MetricsProto.MetricsEvent.TYPE_ACTION, IMPORTANCE_NONE - IMPORTANCE_LOW)); + mTestableLooper.processAllMessages(); ArgumentCaptor<NotificationChannel> updated = ArgumentCaptor.forClass(NotificationChannel.class); @@ -860,6 +891,9 @@ public class NotificationInfoTest extends SysuiTestCase { waitForUndoButton(); mNotificationInfo.handleCloseControls(true, false); + verify(mMetricsLogger).write(importanceChangeLog( + MetricsProto.MetricsEvent.TYPE_ACTION, IMPORTANCE_NONE - IMPORTANCE_LOW)); + mTestableLooper.processAllMessages(); ArgumentCaptor<NotificationChannel> updated = ArgumentCaptor.forClass(NotificationChannel.class); @@ -936,15 +970,14 @@ public class NotificationInfoTest extends SysuiTestCase { waitForUndoButton(); mNotificationInfo.findViewById(R.id.undo).performClick(); waitForStopButton(); - mNotificationInfo.handleCloseControls(true, false); + // mNotificationInfo.handleCloseControls doesn't get called by this interaction. + + verify(mMetricsLogger).write(importanceChangeLog( + MetricsProto.MetricsEvent.TYPE_DISMISS, IMPORTANCE_NONE - IMPORTANCE_LOW)); mTestableLooper.processAllMessages(); - ArgumentCaptor<NotificationChannel> updated = - ArgumentCaptor.forClass(NotificationChannel.class); - verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( - anyString(), eq(TEST_UID), updated.capture()); - assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE)); - assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance()); + verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( + anyString(), eq(TEST_UID), any()); } @Test @@ -958,15 +991,11 @@ public class NotificationInfoTest extends SysuiTestCase { waitForUndoButton(); mNotificationInfo.findViewById(R.id.undo).performClick(); waitForStopButton(); - mNotificationInfo.handleCloseControls(true, false); + // mNotificationInfo.handleCloseControls doesn't get called by this code path mTestableLooper.processAllMessages(); - ArgumentCaptor<NotificationChannel> updated = - ArgumentCaptor.forClass(NotificationChannel.class); - verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( - anyString(), eq(TEST_UID), updated.capture()); - assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE)); - assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance()); + verify(mMockINotificationManager, times(0)).updateNotificationChannelForPackage( + anyString(), eq(TEST_UID), any()); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index b4f99c4ed156..b8c7ee093ecc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -130,7 +130,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mContext); mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); Dependency.get(InitController.class).executePostInitTasks(); - mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, null, mHeadsUpManager, + mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, mHeadsUpManager, mNotificationData); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java index 4f6329cb0c57..38d9ae7cfab4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java @@ -30,11 +30,11 @@ import android.view.View; import android.widget.TextView; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.HeadsUpStatusBarView; import com.android.systemui.statusbar.NotificationTestHelper; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import org.junit.Assert; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java index 728723b4094c..babd452475d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java @@ -40,7 +40,6 @@ import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.DeviceProvisionedController; -import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl; import org.junit.Before; import org.junit.Test; @@ -105,7 +104,7 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest { @Override protected Fragment instantiate(Context context, String className, Bundle arguments) { DeviceProvisionedController deviceProvisionedController = - new DeviceProvisionedControllerImpl(context); + mock(DeviceProvisionedController.class); assertNotNull(mAccessibilityWrapper); return new NavigationBarFragment(mAccessibilityWrapper, deviceProvisionedController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java index 76f57f049561..40d5415a9a47 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java @@ -67,5 +67,4 @@ public class NavigationBarTransitionsTest extends SysuiTestCase { assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT)); } - }
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java index 490288efd40f..56af40054316 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java @@ -237,7 +237,8 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase { mGroupManager.onEntryAdded(summaryEntry); mGroupManager.onEntryAdded(childEntry); - mNotificationEntryListener.onEntryRemoved(childEntry); + mNotificationEntryListener.onEntryRemoved(childEntry, childEntry.key, null, null, + false, false); assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 0bc304ee41b2..146c5d647198 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -220,9 +220,9 @@ public class ScrimControllerTest extends SysuiTestCase { mScrimController.transitionTo(ScrimState.PULSING); mScrimController.finishAnimationsImmediately(); // Front scrim should be transparent - // Back scrim should be visible with tint + // Back scrim should be semi-transparent so the user can see the wallpaper // Pulse callback should have been invoked - assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE); + assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT); assertScrimTint(mScrimBehind, true /* tinted */); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java index 72b0156d25f9..4f95bc515d0a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java @@ -14,17 +14,14 @@ package com.android.systemui.statusbar.phone; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; - import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_ICON; import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE; import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI; -import static org.mockito.ArgumentMatchers.eq; + +import static junit.framework.Assert.assertTrue; + import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import android.graphics.Rect; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; @@ -32,15 +29,15 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import com.android.internal.statusbar.StatusBarIcon; -import com.android.systemui.statusbar.StatusIconDisplayable; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarMobileView; import com.android.systemui.statusbar.StatusBarWifiView; +import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager; import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index 02f894922959..4fabe7f8cfbb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -37,6 +37,7 @@ import com.android.internal.logging.testing.FakeMetricsLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; +import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; @@ -70,7 +71,8 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mock(NotificationPanelView.class), mock(HeadsUpManagerPhone.class), statusBarWindowView, mock(NotificationListContainerViewGroup.class), mock(DozeScrimController.class), mock(ScrimController.class), - mock(ActivityLaunchAnimator.class), mock(StatusBarKeyguardViewManager.class)); + mock(ActivityLaunchAnimator.class), mock(StatusBarKeyguardViewManager.class), + mock(NotificationAlertingManager.class)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index c584d026f62b..18ead907ae8e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -67,7 +67,9 @@ import com.android.systemui.Dependency; import com.android.systemui.ForegroundServiceController; import com.android.systemui.InitController; import com.android.systemui.R; +import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; +import com.android.systemui.UiOffloadThread; import com.android.systemui.appops.AppOpsController; import com.android.systemui.appops.AppOpsControllerImpl; import com.android.systemui.assist.AssistManager; @@ -80,6 +82,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; @@ -90,6 +93,7 @@ import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationData.Entry; import com.android.systemui.statusbar.notification.NotificationEntryListener; @@ -148,10 +152,12 @@ public class StatusBarTest extends SysuiTestCase { @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private NotificationPresenter mNotificationPresenter; @Mock - private NotificationEntryListener mCallback; + private NotificationEntryListener mEntryListener; @Mock private BubbleController mBubbleController; @Mock private NotificationFilter mNotificationFilter; + @Mock + private NotificationAlertingManager mNotificationAlertingManager; private TestableStatusBar mStatusBar; private FakeMetricsLogger mMetricsLogger; @@ -179,6 +185,8 @@ public class StatusBarTest extends SysuiTestCase { mDeviceProvisionedController); mDependency.injectMockDependency(BubbleController.class); mDependency.injectTestDependency(NotificationFilter.class, mNotificationFilter); + mDependency.injectTestDependency(NotificationAlertingManager.class, + mNotificationAlertingManager); IPowerManager powerManagerService = mock(IPowerManager.class); mPowerManager = new PowerManager(mContext, powerManagerService, @@ -189,14 +197,17 @@ public class StatusBarTest extends SysuiTestCase { mDreamManager); mDependency.injectTestDependency(NotificationInterruptionStateProvider.class, mNotificationInterruptionStateProvider); + mDependency.injectMockDependency(NavigationBarController.class); mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class)); mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class)); mMetricsLogger = new FakeMetricsLogger(); mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); + mEntryManager = new TestableNotificationEntryManager(mPowerManager, mContext); + mNotificationLogger = new NotificationLogger(mNotificationListener, + Dependency.get(UiOffloadThread.class), mEntryManager, mStatusBarStateController); mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger); - mNotificationLogger = new NotificationLogger(); DozeLog.traceDozing(mContext, false /* dozing */); mCommandQueue = mock(CommandQueue.class); @@ -225,7 +236,6 @@ public class StatusBarTest extends SysuiTestCase { mNotificationInterruptionStateProvider.setUpWithPresenter(mNotificationPresenter, mHeadsUpManager, mHeadsUpSuppressor); - mEntryManager = new TestableNotificationEntryManager(mPowerManager, mContext); when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController); mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache, mKeyguardIndicationController, mStackScroller, mHeadsUpManager, @@ -237,13 +247,17 @@ public class StatusBarTest extends SysuiTestCase { mock(StatusBarWindowController.class), mock(NotificationIconAreaController.class), mDozeScrimController, mock(NotificationShelf.class), mLockscreenUserManager, mCommandQueue, mNotificationPresenter, - mock(BubbleController.class)); + mock(BubbleController.class), mock(NavigationBarController.class)); mStatusBar.mContext = mContext; mStatusBar.mComponents = mContext.getComponents(); + SystemUIFactory.getInstance().getRootComponent() + .getStatusBarInjector() + .createStatusBar(mStatusBar); mStatusBar.putComponent(StatusBar.class, mStatusBar); Dependency.get(InitController.class).executePostInitTasks(); mEntryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller, - mCallback, mHeadsUpManager, mNotificationData); + mHeadsUpManager, mNotificationData); + mEntryManager.addNotificationEntryListener(mEntryListener); mNotificationLogger.setUpWithContainer(mStackScroller); TestableLooper.get(this).setMessageHandler(m -> { @@ -683,7 +697,8 @@ public class StatusBarTest extends SysuiTestCase { NotificationLockscreenUserManager notificationLockscreenUserManager, CommandQueue commandQueue, NotificationPresenter notificationPresenter, - BubbleController bubbleController) { + BubbleController bubbleController, + NavigationBarController navBarController) { mStatusBarKeyguardViewManager = man; mUnlockMethodCache = unlock; mKeyguardIndicationController = key; @@ -714,6 +729,7 @@ public class StatusBarTest extends SysuiTestCase { mPresenter = notificationPresenter; mGestureWakeLock = mock(PowerManager.WakeLock.class); mBubbleController = bubbleController; + mNavigationBarController = navBarController; } private WakefulnessLifecycle createAwakeWakefulnessLifecycle() { @@ -747,10 +763,9 @@ public class StatusBarTest extends SysuiTestCase { public void setUpForTest(NotificationPresenter presenter, NotificationListContainer listContainer, - NotificationEntryListener callback, HeadsUpManagerPhone headsUpManager, NotificationData notificationData) { - super.setUpWithPresenter(presenter, listContainer, callback, headsUpManager); + super.setUpWithPresenter(presenter, listContainer, headsUpManager); mNotificationData = notificationData; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java index d54c29582247..e626d083d366 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.policy; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Intent; @@ -26,6 +27,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.systemui.SysuiTestCase; +import com.android.systemui.power.EnhancedEstimates; import org.junit.Assert; import org.junit.Before; @@ -47,7 +49,8 @@ public class BatteryControllerTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mBatteryController = new BatteryControllerImpl(getContext(), mPowerManager); + mBatteryController = new BatteryControllerImpl(getContext(), mock(EnhancedEstimates.class), + mPowerManager); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java index d2463502cb19..b65b0f7afa0b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java @@ -74,7 +74,8 @@ public class BluetoothControllerImplTest extends SysuiTestCase { .thenReturn(mock(LocalBluetoothProfileManager.class)); mBluetoothControllerImpl = new BluetoothControllerImpl(mContext, - mTestableLooper.getLooper()); + mTestableLooper.getLooper(), + mMockBluetoothManager); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java index 1cceefa7910c..2553ac1e8fcb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java @@ -28,7 +28,6 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; -import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.OverlayPlugin; import com.android.systemui.plugins.Plugin; @@ -39,6 +38,7 @@ import com.android.systemui.statusbar.policy.ExtensionController.Extension; import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; +import com.android.systemui.util.leak.LeakDetector; import org.junit.Before; import org.junit.Test; @@ -62,7 +62,8 @@ public class ExtensionControllerImplTest extends SysuiTestCase { mPluginManager = mDependency.injectMockDependency(PluginManager.class); mTunerService = mDependency.injectMockDependency(TunerService.class); mConfigurationController = mDependency.injectMockDependency(ConfigurationController.class); - mExtensionController = Dependency.get(ExtensionController.class); + mExtensionController = new ExtensionControllerImpl(mContext, + mock(LeakDetector.class), mPluginManager, mTunerService, mConfigurationController); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.java index 3b47eae03fa0..e3a41bead26c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.java @@ -29,6 +29,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.policy.ConfigurationController; import org.junit.Before; import org.junit.Test; @@ -49,7 +50,8 @@ public class RemoteInputQuickSettingsDisablerTest extends SysuiTestCase { mCommandQueue = mock(CommandQueue.class); mContext.putComponent(CommandQueue.class, mCommandQueue); - mRemoteInputQuickSettingsDisabler = new RemoteInputQuickSettingsDisabler(mContext); + mRemoteInputQuickSettingsDisabler = new RemoteInputQuickSettingsDisabler(mContext, + mock(ConfigurationController.class)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java index f76de5a03d2d..3ac42de911a9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java @@ -39,6 +39,8 @@ import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.NetworkCapabilities; import android.net.NetworkRequest; +import android.os.Handler; +import android.os.Looper; import android.os.UserManager; import android.security.IKeyChainService; import android.support.test.runner.AndroidJUnit4; @@ -98,7 +100,10 @@ public class SecurityControllerTest extends SysuiTestCase implements SecurityCon // Wait for callbacks from 1) the CACertLoader and 2) the onUserSwitched() function in the // constructor of mSecurityController mStateChangedLatch = new CountDownLatch(2); - mSecurityController = new SecurityControllerImpl(mContext, this); + // TODO: Migrate this test to TestableLooper and use a handler attached + // to that. + mSecurityController = new SecurityControllerImpl(mContext, + new Handler(Looper.getMainLooper()), this); } @After diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java index 7437e83469c6..8f5f0729c3b3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java @@ -89,20 +89,22 @@ public class ZenModeControllerImplTest extends SysuiTestCase { @Test public void testAreNotificationsHiddenInShade_zenOnShadeNotSuppressed() { - mConfig.suppressedVisualEffects = - NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; + NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0, + NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR); + when(mNm.getConsolidatedNotificationPolicy()).thenReturn(policy); + mController.updateConsolidatedNotificationPolicy(); mController.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); - mController.updateZenModeConfig(); assertFalse(mController.areNotificationsHiddenInShade()); } @Test public void testAreNotificationsHiddenInShade_zenOnShadeSuppressed() { - mConfig.suppressedVisualEffects = - NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST; + NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0, + NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST); + when(mNm.getConsolidatedNotificationPolicy()).thenReturn(policy); + mController.updateConsolidatedNotificationPolicy(); mController.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); - mController.updateZenModeConfig(); assertTrue(mController.areNotificationsHiddenInShade()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java index 3bfefe7b4d9b..1e27915c1bb2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java @@ -48,7 +48,9 @@ public class TunablePaddingTest extends LeakCheckedTest { mView = mock(View.class); when(mView.getContext()).thenReturn(mContext); - mTunerService = mDependency.injectMockDependency(TunerService.class); + mTunerService = mock(TunerService.class); + mDependency.injectTestDependency(TunablePadding.TunablePaddingService.class, + new TunablePadding.TunablePaddingService(mTunerService)); Tracker tracker = mLeakCheck.getTracker("tuner"); doAnswer(invocation -> { tracker.getLeakInfo(invocation.getArguments()[0]).addAllocation(new Throwable()); @@ -118,4 +120,4 @@ public class TunablePaddingTest extends LeakCheckedTest { mTunablePadding.destroy(); } -}
\ No newline at end of file +} diff --git a/packages/overlays/FontArbutusSourceOverlay/Android.mk b/packages/overlays/FontArbutusSourceOverlay/Android.mk new file mode 100644 index 000000000000..23aee558257a --- /dev/null +++ b/packages/overlays/FontArbutusSourceOverlay/Android.mk @@ -0,0 +1,31 @@ +# +# 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 := FontArbutusSource +LOCAL_CERTIFICATE := platform +LOCAL_PRODUCT_MODULE := true + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := FontArbutusSourceOverlay +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/packages/overlays/FontArbutusSourceOverlay/AndroidManifest.xml b/packages/overlays/FontArbutusSourceOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..46c06b969461 --- /dev/null +++ b/packages/overlays/FontArbutusSourceOverlay/AndroidManifest.xml @@ -0,0 +1,31 @@ +<!-- +/** + * 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.theme.font.arbutussource" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="android" + android:category="android.theme.customization.font" + android:priority="1"/> + + <application android:label="@string/font_arbutus_source_overlay" android:hasCode="false"> + <meta-data + android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS" + android:value="arbutus-slab,source-sans-pro,source-sans-pro-medium" /> + </application> +</manifest> diff --git a/packages/overlays/FontArbutusSourceOverlay/res/values/config.xml b/packages/overlays/FontArbutusSourceOverlay/res/values/config.xml new file mode 100644 index 000000000000..165aab21c2e8 --- /dev/null +++ b/packages/overlays/FontArbutusSourceOverlay/res/values/config.xml @@ -0,0 +1,28 @@ +<!-- +/** + * 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 a font family to use for body text. --> + <string name="config_bodyFontFamily" translatable="false">source-sans-pro</string> + <!-- Name of a font family to use for medium body text. --> + <string name="config_bodyFontFamilyMedium" translatable="false">source-sans-pro-medium</string> + <!-- Name of a font family to use for headlines. If empty, falls back to platform default --> + <string name="config_headlineFontFamily" translatable="false">arbutus-slab</string> + <!-- Name of the font family used for system surfaces where the font should use medium weight --> + <string name="config_headlineFontFamilyMedium" translatable="false">arbutus-slab</string> +</resources> + diff --git a/packages/overlays/FontArbutusSourceOverlay/res/values/strings.xml b/packages/overlays/FontArbutusSourceOverlay/res/values/strings.xml new file mode 100644 index 000000000000..d80eb20677c1 --- /dev/null +++ b/packages/overlays/FontArbutusSourceOverlay/res/values/strings.xml @@ -0,0 +1,21 @@ +<!-- +/** + * 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"> + <!-- Headline / Body font Arbutus Slab / Source Sans Pro overlay --> + <string name="font_arbutus_source_overlay" translatable="false">Arbutus Slab / Source Sans Pro</string> +</resources> diff --git a/packages/overlays/FontArvoLatoOverlay/Android.mk b/packages/overlays/FontArvoLatoOverlay/Android.mk new file mode 100644 index 000000000000..3433ecfd1f6b --- /dev/null +++ b/packages/overlays/FontArvoLatoOverlay/Android.mk @@ -0,0 +1,31 @@ +# +# 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 := FontArvoLato +LOCAL_CERTIFICATE := platform +LOCAL_PRODUCT_MODULE := true + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := FontArvoLatoOverlay +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/packages/overlays/FontArvoLatoOverlay/AndroidManifest.xml b/packages/overlays/FontArvoLatoOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..3f2e5de39c0b --- /dev/null +++ b/packages/overlays/FontArvoLatoOverlay/AndroidManifest.xml @@ -0,0 +1,31 @@ +<!-- +/** + * 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.theme.font.arvolato" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="android" + android:category="android.theme.customization.font" + android:priority="1"/> + + <application android:label="@string/font_arvo_lato_overlay" android:hasCode="false"> + <meta-data + android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS" + android:value="arvo,arvo-medium,lato,lato-medium" /> + </application> +</manifest> diff --git a/packages/overlays/FontArvoLatoOverlay/res/values/config.xml b/packages/overlays/FontArvoLatoOverlay/res/values/config.xml new file mode 100644 index 000000000000..229c578b22da --- /dev/null +++ b/packages/overlays/FontArvoLatoOverlay/res/values/config.xml @@ -0,0 +1,28 @@ +<!-- +/** + * 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 a font family to use for body text. --> + <string name="config_bodyFontFamily" translatable="false">lato</string> + <!-- Name of a font family to use for medium body text. --> + <string name="config_bodyFontFamilyMedium" translatable="false">lato-medium</string> + <!-- Name of a font family to use for headlines. If empty, falls back to platform default --> + <string name="config_headlineFontFamily" translatable="false">arvo</string> + <!-- Name of the font family used for system surfaces where the font should use medium weight --> + <string name="config_headlineFontFamilyMedium" translatable="false">arvo-medium</string> +</resources> + diff --git a/packages/overlays/FontArvoLatoOverlay/res/values/strings.xml b/packages/overlays/FontArvoLatoOverlay/res/values/strings.xml new file mode 100644 index 000000000000..9ea097f1fe48 --- /dev/null +++ b/packages/overlays/FontArvoLatoOverlay/res/values/strings.xml @@ -0,0 +1,21 @@ +<!-- +/** + * 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"> + <!-- Headline / Body font Arvo / Lato overlay --> + <string name="font_arvo_lato_overlay" translatable="false">Arvo / Lato</string> +</resources> diff --git a/packages/overlays/FontRubikRubikOverlay/Android.mk b/packages/overlays/FontRubikRubikOverlay/Android.mk new file mode 100644 index 000000000000..21d617ef2c72 --- /dev/null +++ b/packages/overlays/FontRubikRubikOverlay/Android.mk @@ -0,0 +1,31 @@ +# +# 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 := FontRubikRubik +LOCAL_CERTIFICATE := platform +LOCAL_PRODUCT_MODULE := true + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := FontRubikRubikOverlay +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/packages/overlays/FontRubikRubikOverlay/AndroidManifest.xml b/packages/overlays/FontRubikRubikOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..1f28d46f087a --- /dev/null +++ b/packages/overlays/FontRubikRubikOverlay/AndroidManifest.xml @@ -0,0 +1,31 @@ +<!-- +/** + * 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.theme.font.rubikrubik" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="android" + android:category="android.theme.customization.font" + android:priority="1"/> + + <application android:label="@string/font_rubik_rubik_overlay" android:hasCode="false"> + <meta-data + android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS" + android:value="rubik,rubik-medium" /> + </application> +</manifest> diff --git a/packages/overlays/FontRubikRubikOverlay/res/values/config.xml b/packages/overlays/FontRubikRubikOverlay/res/values/config.xml new file mode 100644 index 000000000000..4f90e292e2f4 --- /dev/null +++ b/packages/overlays/FontRubikRubikOverlay/res/values/config.xml @@ -0,0 +1,28 @@ +<!-- +/** + * 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 a font family to use for body text. --> + <string name="config_bodyFontFamily" translatable="false">rubik</string> + <!-- Name of a font family to use for medium body text. --> + <string name="config_bodyFontFamilyMedium" translatable="false">rubik-medium</string> + <!-- Name of a font family to use for headlines. If empty, falls back to platform default --> + <string name="config_headlineFontFamily" translatable="false">rubik</string> + <!-- Name of the font family used for system surfaces where the font should use medium weight --> + <string name="config_headlineFontFamilyMedium" translatable="false">rubik-medium</string> +</resources> + diff --git a/packages/overlays/FontRubikRubikOverlay/res/values/strings.xml b/packages/overlays/FontRubikRubikOverlay/res/values/strings.xml new file mode 100644 index 000000000000..4bac7da0aa73 --- /dev/null +++ b/packages/overlays/FontRubikRubikOverlay/res/values/strings.xml @@ -0,0 +1,21 @@ +<!-- +/** + * 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"> + <!-- Headline / Body font Rubik overlay --> + <string name="font_rubik_rubik_overlay" translatable="false">Rubik / Rubik</string> +</resources> diff --git a/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml b/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml index f024615190ab..138c283b9a24 100644 --- a/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml +++ b/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml @@ -18,7 +18,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. --> - <string name="config_icon_mask" translatable="false">"M50,0L92,0C96.42,0 100,4.58 100 8L100,92C100, 96.42 96.42 100 92 100L8 100C4.58, 100 0 96.42 0 92L0 8 C 0 4.42 4.42 0 8 0L50 0Z"</string> + <string name="config_icon_mask" translatable="false">"M50,0L88,0 C94.4,0 100,5.4 100 12 L100,88 C100,94.6 94.6 100 88 100 L12,100 C5.4,100 0,94.6 0,88 L0 12 C0 5.4 5.4 0 12 0 L50,0 Z"</string> <!-- Flag indicating whether round icons should be parsed from the application manifest. --> <bool name="config_useRoundIcon">false</bool> diff --git a/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml b/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml index 43ad04d69c73..818e696577e9 100644 --- a/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml +++ b/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml @@ -18,7 +18,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. --> - <string name="config_icon_mask" translatable="false">"M50,0A50,50,0,0 1 100,50 L100,85 A15,15,0,0 1 85,100 L50,100 A50,50,0,0 1 50,0z"</string> + <string name="config_icon_mask" translatable="false">"M50,0 C77.6,0 100,22.4 100,50 L100,88 C100,94.6 94.6,100 88,100 L50,100 C22.4 100 0 77.6 0 50C0 22.4 22.4 0 50 0 Z"</string> <!-- Flag indicating whether round icons should be parsed from the application manifest. --> <bool name="config_useRoundIcon">false</bool> diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto index 529d78f577ed..3180b479b520 100644 --- a/proto/src/metrics_constants/metrics_constants.proto +++ b/proto/src/metrics_constants/metrics_constants.proto @@ -6664,6 +6664,72 @@ message MetricsEvent { // OS: Q NOTIFICATION_ACTION_IS_SMART = 1601; + // FIELD: true if the associated ACTION_ZEN_ALLOW_* or ACTION_ZEN_BLOCK_* allows/blocks + // the effect/sound when DND is on. false if set to disallow/show. + // OS: Q + FIELD_ZEN_TOGGLE_EXCEPTION = 1602; + + // FIELD: rule id an ACTION_ZEN_ALLOW_* or ACTION_ZEN_BLOCK_* is associated with + // OS: Q + FIELD_ZEN_RULE_ID = 1603; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_SETTINGS = 1604; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior > Custom + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_SOUND_SETTINGS = 1605; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior > Use default Do Not Disturb behavior + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_DEFAULT_SETTINGS = 1606; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior > Custom + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_CUSTOM_SETTINGS = 1607; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior > Use default Do Not Disturb behavior + // > Notification restriction + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS = 1608; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior > Use default Do Not Disturb behavior + // > Notification restriction > Custom + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_VIS_EFFECTS = 1609; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior > Use default Do Not Disturb behavior + // > Notification restriction > Custom > Allow messages + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_MESSAGES = 1610; + + // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) + // > Do Not Disturb behavior > Use default Do Not Disturb behavior + // > Notification restriction > Custom > Allow calls + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_RULE_CALLS = 1611; + + // OPEN: Settings > Sound > Do Not Disturb > Click footer link if custom settings applied + // CATEGORY: SETTINGS + // OS: Q + ZEN_CUSTOM_SETTINGS_DIALOG = 1612; + // ---- End Q Constants, all Q constants go above this line ---- // Add new aosp constants above this line. diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index 612c9294f5d1..1a6bee9daaf3 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -74,6 +74,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.SecureSettingsServiceNameResolver; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -182,7 +183,9 @@ public final class AutofillManagerService private int mSupportedSmartSuggestionModes; public AutofillManagerService(Context context) { - super(context, UserManager.DISALLOW_AUTOFILL); + super(context, + new SecureSettingsServiceNameResolver(context, Settings.Secure.AUTOFILL_SERVICE), + UserManager.DISALLOW_AUTOFILL); mUi = new AutoFillUI(ActivityThread.currentActivityThread().getSystemUiContext()); mAm = LocalServices.getService(ActivityManagerInternal.class); @@ -523,7 +526,7 @@ public final class AutofillManagerService synchronized (mLock) { final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); if (service != null) { - service.mAugmentedAutofillResolver.setTemporaryServiceLocked(serviceName, + service.mAugmentedAutofillResolver.setTemporaryService(userId, serviceName, durationMs); } } @@ -535,7 +538,7 @@ public final class AutofillManagerService synchronized (mLock) { final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); if (service != null) { - service.mAugmentedAutofillResolver.resetTemporaryServiceLocked(); + service.mAugmentedAutofillResolver.resetTemporaryService(userId); } } } diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index fa62ef829b32..4b7efe1dfa71 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -77,7 +77,6 @@ import com.android.server.autofill.RemoteAugmentedAutofillService.RemoteAugmente import com.android.server.autofill.ui.AutoFillUI; import com.android.server.infra.AbstractPerUserSystemService; import com.android.server.infra.FrameworkResourcesServiceNameResolver; -import com.android.server.infra.SecureSettingsServiceNameResolver; import java.io.PrintWriter; import java.util.ArrayList; @@ -170,8 +169,7 @@ final class AutofillManagerServiceImpl AutofillManagerServiceImpl(AutofillManagerService master, Object lock, LocalLog requestsHistory, LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui, AutofillCompatState autofillCompatState, boolean disabled) { - super(master, new SecureSettingsServiceNameResolver(master.getContext(), userId, - Settings.Secure.AUTOFILL_SERVICE), lock, userId); + super(master, lock, userId); mRequestsHistory = requestsHistory; mUiLatencyHistory = uiLatencyHistory; @@ -181,9 +179,9 @@ final class AutofillManagerServiceImpl mAutofillCompatState = autofillCompatState; mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(master.getContext(), - userId, lock, com.android.internal.R.string.config_defaultAugmentedAutofillService); + com.android.internal.R.string.config_defaultAugmentedAutofillService); mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback( - () -> updateRemoteAugmentedAutofillService()); + (u, s) -> updateRemoteAugmentedAutofillService()); updateLocked(disabled); } @@ -207,7 +205,7 @@ final class AutofillManagerServiceImpl } @Override // from PerUserSystemService - protected ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent) + protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent) throws NameNotFoundException { mInfo = new AutofillServiceInfo(getContext(), serviceComponent, mUserId); return mInfo.getServiceInfo(); @@ -873,7 +871,7 @@ final class AutofillManagerServiceImpl pw.print(prefix); pw.print("Default component: "); pw.println(getContext() .getString(R.string.config_defaultAutofillService)); pw.print(prefix); pw.print("mAugmentedAutofillNamer: "); - mAugmentedAutofillResolver.dumpShortLocked(pw); pw.println(); + mAugmentedAutofillResolver.dumpShort(pw); pw.println(); if (mRemoteAugmentedAutofillService != null) { pw.print(prefix); pw.println("RemoteAugmentedAutofillService: "); mRemoteAugmentedAutofillService.dump(prefix2, pw); @@ -1022,7 +1020,7 @@ final class AutofillManagerServiceImpl @GuardedBy("mLock") @Nullable RemoteAugmentedAutofillService getRemoteAugmentedAutofillServiceLocked() { if (mRemoteAugmentedAutofillService == null) { - final String serviceName = mAugmentedAutofillResolver.getServiceNameLocked(); + final String serviceName = mAugmentedAutofillResolver.getServiceName(mUserId); if (serviceName == null) { if (mMaster.verbose) { Slog.v(TAG, "getRemoteAugmentedAutofillServiceLocked(): not set"); @@ -1030,7 +1028,7 @@ final class AutofillManagerServiceImpl return null; } final ComponentName componentName = RemoteAugmentedAutofillService.getComponentName( - serviceName, mUserId, mAugmentedAutofillResolver.isTemporaryLocked()); + serviceName, mUserId, mAugmentedAutofillResolver.isTemporary(mUserId)); if (componentName == null) return null; if (sVerbose) { Slog.v(TAG, "getRemoteAugmentedAutofillServiceLocked(): " + componentName); @@ -1053,7 +1051,7 @@ final class AutofillManagerServiceImpl * Called when the {@link #mAugmentedAutofillResolver} changed (among other places). */ private void updateRemoteAugmentedAutofillService() { - final String serviceName = mAugmentedAutofillResolver.getServiceNameLocked(); + final String serviceName = mAugmentedAutofillResolver.getServiceName(mUserId); if (serviceName == null) { if (sVerbose) Slog.v(TAG, "updateRemoteAugmentedAutofillService(): time's up!"); if (mRemoteAugmentedAutofillService != null) { diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java index 681a9941faea..239a386aefcc 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java @@ -47,8 +47,6 @@ final class RemoteAugmentedAutofillService private static final String TAG = RemoteAugmentedAutofillService.class.getSimpleName(); - // TODO(b/117779333): changed it so it's permanentely bound - private static final long TIMEOUT_IDLE_BIND_MILLIS = 2 * DateUtils.MINUTE_IN_MILLIS; private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS; RemoteAugmentedAutofillService(Context context, ComponentName serviceName, @@ -90,7 +88,7 @@ final class RemoteAugmentedAutofillService @Override // from AbstractRemoteService protected long getTimeoutIdleBindMillis() { - return TIMEOUT_IDLE_BIND_MILLIS; + return PERMANENT_BOUND_TIMEOUT_MS; } @Override // from AbstractRemoteService diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java index e5529aff7c62..34fe5d916356 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java @@ -77,7 +77,7 @@ final class RemoteFillService try { mService.onConnectedStateChanged(state); } catch (Exception e) { - Slog.w(mTag, "Exception calling onConnectedStateChanged(): " + e); + Slog.w(mTag, "Exception calling onConnectedStateChanged(" + state + "): " + e); } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 0e9b407372e0..0348f2bf1c2b 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -64,9 +64,11 @@ import android.os.RemoteException; import android.os.SystemClock; import android.service.autofill.AutofillFieldClassificationService.Scores; import android.service.autofill.AutofillService; +import android.service.autofill.CompositeUserData; import android.service.autofill.Dataset; import android.service.autofill.FieldClassification; import android.service.autofill.FieldClassification.Match; +import android.service.autofill.FieldClassificationUserData; import android.service.autofill.FillContext; import android.service.autofill.FillRequest; import android.service.autofill.FillResponse; @@ -1237,11 +1239,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } + // Merge UserData if necessary. + // Fields in packageUserData will override corresponding fields in genericUserData. + final UserData genericUserData = mService.getUserData(); final UserData packageUserData = lastResponse.getUserData(); - - final UserData userData; - if (packageUserData != null) { - // Replace default userData + final FieldClassificationUserData userData; + if (packageUserData == null && genericUserData == null) { + userData = null; + } else if (packageUserData != null && genericUserData != null) { + userData = new CompositeUserData(genericUserData, packageUserData); + } else if (packageUserData != null) { userData = packageUserData; } else { userData = mService.getUserData(); @@ -1396,7 +1403,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @NonNull ArrayList<String> changedDatasetIds, @NonNull ArrayList<AutofillId> manuallyFilledFieldIds, @NonNull ArrayList<ArrayList<String>> manuallyFilledDatasetIds, - @NonNull UserData userData, @NonNull Collection<ViewState> viewStates) { + @NonNull FieldClassificationUserData userData, + @NonNull Collection<ViewState> viewStates) { final String[] userValues = userData.getValues(); final String[] categoryIds = userData.getCategoryIds(); diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 704974417f87..8b07db7fc32d 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -36,7 +36,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Binder; -import android.os.Environment; import android.os.HandlerThread; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -50,11 +49,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.server.SystemConfig; import com.android.server.SystemService; -import java.io.File; import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; import java.io.PrintWriter; import java.util.Collections; import java.util.Set; @@ -72,10 +67,6 @@ public class BackupManagerService { public static final boolean MORE_DEBUG = false; public static final boolean DEBUG_SCHEDULING = true; - // File containing backup-enabled state. Contains a single byte to denote enabled status. - // Nonzero is enabled; file missing or a zero byte is disabled. - private static final String BACKUP_ENABLE_FILE = "backup_enabled"; - // The published binder is a singleton Trampoline object that calls through to the proper code. // This indirection lets us turn down the heavy implementation object on the fly without // disturbing binders that have been cached elsewhere in the system. @@ -150,7 +141,8 @@ public class BackupManagerService { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable"); try { // TODO(b/121198604): Make enable file per-user and clean up indirection. - mTrampoline.setBackupEnabledForUser(userId, readBackupEnableState(userId)); + mTrampoline.setBackupEnabledForUser( + userId, UserBackupManagerFilePersistedSettings.readBackupEnableState(userId)); } catch (RemoteException e) { // Can't happen, it's a local object. } @@ -773,44 +765,6 @@ public class BackupManagerService { } } - private static boolean readBackupEnableState(int userId) { - File base = new File(Environment.getDataDirectory(), "backup"); - File enableFile = new File(base, BACKUP_ENABLE_FILE); - if (enableFile.exists()) { - try (FileInputStream fin = new FileInputStream(enableFile)) { - int state = fin.read(); - return state != 0; - } catch (IOException e) { - // can't read the file; fall through to assume disabled - Slog.e(TAG, "Cannot read enable state; assuming disabled"); - } - } else { - if (DEBUG) { - Slog.i(TAG, "isBackupEnabled() => false due to absent settings file"); - } - } - return false; - } - - static void writeBackupEnableState(boolean enable, int userId) { - File base = new File(Environment.getDataDirectory(), "backup"); - File enableFile = new File(base, BACKUP_ENABLE_FILE); - File stage = new File(base, BACKUP_ENABLE_FILE + "-stage"); - try (FileOutputStream fout = new FileOutputStream(stage)) { - fout.write(enable ? 1 : 0); - fout.close(); - stage.renameTo(enableFile); - // will be synced immediately by the try-with-resources call to close() - } catch (IOException | RuntimeException e) { - Slog.e( - TAG, - "Unable to record backup enable state; reverting to disabled: " - + e.getMessage()); - enableFile.delete(); - stage.delete(); - } - } - /** Implementation to receive lifecycle event callbacks for system services. */ public static final class Lifecycle extends SystemService { public Lifecycle(Context context) { diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java index 8eb5207e4dca..79d4a2cb33de 100644 --- a/services/backup/java/com/android/server/backup/Trampoline.java +++ b/services/backup/java/com/android/server/backup/Trampoline.java @@ -386,13 +386,6 @@ public class Trampoline extends IBackupManager.Stub { } @Override - public void setBackupProvisioned(boolean isProvisioned) throws RemoteException { - /* - * This is now a no-op; provisioning is simply the device's own setup state. - */ - } - - @Override public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException { BackupManagerService svc = mService; return (svc != null) ? svc.isBackupEnabled(userId) : false; diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java new file mode 100644 index 000000000000..6a1de6378a5e --- /dev/null +++ b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java @@ -0,0 +1,78 @@ +/* + * 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.server.backup; + +import static com.android.server.backup.BackupManagerService.DEBUG; +import static com.android.server.backup.BackupManagerService.TAG; + +import android.util.Slog; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** User settings which are persisted across reboots. */ +final class UserBackupManagerFilePersistedSettings { + // File containing backup-enabled state. Contains a single byte to denote enabled status. + // Nonzero is enabled; file missing or a zero byte is disabled. + private static final String BACKUP_ENABLE_FILE = "backup_enabled"; + + static boolean readBackupEnableState(int userId) { + return readBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId)); + } + + static void writeBackupEnableState(int userId, boolean enable) { + writeBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId), enable); + } + + private static boolean readBackupEnableState(File baseDir) { + File enableFile = new File(baseDir, BACKUP_ENABLE_FILE); + if (enableFile.exists()) { + try (FileInputStream fin = new FileInputStream(enableFile)) { + int state = fin.read(); + return state != 0; + } catch (IOException e) { + // can't read the file; fall through to assume disabled + Slog.e(TAG, "Cannot read enable state; assuming disabled"); + } + } else { + if (DEBUG) { + Slog.i(TAG, "isBackupEnabled() => false due to absent settings file"); + } + } + return false; + } + + private static void writeBackupEnableState(File baseDir, boolean enable) { + File enableFile = new File(baseDir, BACKUP_ENABLE_FILE); + File stage = new File(baseDir, BACKUP_ENABLE_FILE + "-stage"); + try (FileOutputStream fout = new FileOutputStream(stage)) { + fout.write(enable ? 1 : 0); + fout.close(); + stage.renameTo(enableFile); + // will be synced immediately by the try-with-resources call to close() + } catch (IOException | RuntimeException e) { + Slog.e( + TAG, + "Unable to record backup enable state; reverting to disabled: " + + e.getMessage()); + enableFile.delete(); + stage.delete(); + } + } +} diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java new file mode 100644 index 000000000000..a0feaf9c8d15 --- /dev/null +++ b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java @@ -0,0 +1,45 @@ +/* + * 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.server.backup; + +import android.os.Environment; + +import java.io.File; + +/** Directories used for user specific backup/restore persistent state and book-keeping. */ +public final class UserBackupManagerFiles { + // Name of the directories the service stores bookkeeping data under. + private static final String BACKUP_PERSISTENT_DIR = "backup"; + private static final String BACKUP_STAGING_DIR = "backup_stage"; + + static File getBaseStateDir(int userId) { + // TODO (b/120424138) this should be per user + return new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR); + } + + static File getDataDir(int userId) { + // TODO (b/120424138) this should be per user + // This dir on /cache is managed directly in init.rc + return new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR); + } + + /** Directory used by full backup engine to store state. */ + public static File getFullBackupEngineFilesDir(int userId) { + // TODO (b/120424138) this should be per user + return new File("/data/system"); + } +} diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 2e414438c6ff..6425508829ce 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -70,7 +70,6 @@ import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; import android.os.Bundle; -import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -164,17 +163,9 @@ import java.util.concurrent.atomic.AtomicInteger; /** System service that performs backup/restore operations. */ public class UserBackupManagerService { - // File containing backup-enabled state. Contains a single byte; - // nonzero == enabled. File missing or contains a zero byte == disabled. - private static final String BACKUP_ENABLE_FILE = "backup_enabled"; - // Persistently track the need to do a full init. private static final String INIT_SENTINEL_FILE_NAME = "_need_init_"; - // Name of the directories the service stores bookkeeping data under. - private static final String BACKUP_PERSISTENT_DIR = "backup"; - private static final String BACKUP_STAGING_DIR = "backup_stage"; - // System-private key used for backing up an app's widget state. Must // begin with U+FFxx by convention (we reserve all keys starting // with U+FF00 or higher for system use). @@ -354,9 +345,9 @@ public class UserBackupManagerService { final AtomicInteger mNextToken = new AtomicInteger(); // Where we keep our journal files and other bookkeeping. - private File mBaseStateDir; - private File mDataDir; - private File mJournalDir; + private final File mBaseStateDir; + private final File mDataDir; + private final File mJournalDir; @Nullable private DataChangedJournal mJournal; private File mFullBackupScheduleFile; @@ -395,10 +386,8 @@ public class UserBackupManagerService { TransportManager transportManager = new TransportManager(context, transportWhitelist, currentTransport); - File baseStateDir = new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR); - - // This dir on /cache is managed directly in init.rc - File dataDir = new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR); + File baseStateDir = UserBackupManagerFiles.getBaseStateDir(userId); + File dataDir = UserBackupManagerFiles.getDataDir(userId); return createAndInitializeService( userId, context, trampoline, backupThread, baseStateDir, dataDir, transportManager); @@ -726,18 +715,10 @@ public class UserBackupManagerService { return mBaseStateDir; } - public void setBaseStateDir(File baseStateDir) { - mBaseStateDir = baseStateDir; - } - public File getDataDir() { return mDataDir; } - public void setDataDir(File dataDir) { - mDataDir = dataDir; - } - @Nullable public DataChangedJournal getJournal() { return mJournal; @@ -2735,8 +2716,7 @@ public class UserBackupManagerService { try { boolean wasEnabled = mEnabled; synchronized (this) { - // TODO(b/118520567): Clean up writing backup enabled logic. - BackupManagerService.writeBackupEnableState(enable, UserHandle.USER_SYSTEM); + UserBackupManagerFilePersistedSettings.writeBackupEnableState(mUserId, enable); mEnabled = enable; } diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java index 5e923393843e..45ca2af54b52 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java +++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java @@ -24,6 +24,7 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_METADATA import static com.android.server.backup.UserBackupManagerService.OP_TYPE_BACKUP_WAIT; import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE; +import android.annotation.UserIdInt; import android.app.ApplicationThreadConstants; import android.app.IBackupAgent; import android.app.backup.BackupTransport; @@ -40,6 +41,7 @@ import com.android.internal.util.Preconditions; import com.android.server.AppWidgetBackupBridge; import com.android.server.backup.BackupAgentTimeoutParameters; import com.android.server.backup.BackupRestoreTask; +import com.android.server.backup.UserBackupManagerFiles; import com.android.server.backup.UserBackupManagerService; import com.android.server.backup.remote.RemoteCall; import com.android.server.backup.utils.FullBackupUtils; @@ -66,6 +68,7 @@ public class FullBackupEngine { private final BackupAgentTimeoutParameters mAgentTimeoutParameters; class FullBackupRunner implements Runnable { + private final @UserIdInt int mUserId; private final PackageManager mPackageManager; private final PackageInfo mPackage; private final IBackupAgent mAgent; @@ -81,13 +84,15 @@ public class FullBackupEngine { int token, boolean includeApks) throws IOException { + // TODO: http://b/22388012 + mUserId = UserHandle.USER_SYSTEM; mPackageManager = backupManagerService.getPackageManager(); mPackage = packageInfo; mAgent = agent; mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor()); mToken = token; mIncludeApks = includeApks; - mFilesDir = new File("/data/system"); + mFilesDir = UserBackupManagerFiles.getFullBackupEngineFilesDir(mUserId); } @Override @@ -114,10 +119,8 @@ public class FullBackupEngine { manifestFile.delete(); // Write widget data. - // TODO: http://b/22388012 byte[] widgetData = - AppWidgetBackupBridge.getWidgetState( - packageName, UserHandle.USER_SYSTEM); + AppWidgetBackupBridge.getWidgetState(packageName, mUserId); if (widgetData != null && widgetData.length > 0) { File metadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME); appMetadataBackupWriter.backupWidget( diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 0b3fa0269bd3..4b24ef96cc25 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -41,6 +41,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.infra.AbstractMasterSystemService; +import com.android.server.infra.FrameworkResourcesServiceNameResolver; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -66,14 +67,16 @@ public final class ContentCaptureManagerService extends private final LocalService mLocalService = new LocalService(); - public ContentCaptureManagerService(Context context) { - super(context, UserManager.DISALLOW_CONTENT_CAPTURE); + public ContentCaptureManagerService(@NonNull Context context) { + super(context, new FrameworkResourcesServiceNameResolver(context, + com.android.internal.R.string.config_defaultContentCaptureService), + UserManager.DISALLOW_CONTENT_CAPTURE); } @Override // from AbstractMasterSystemService protected ContentCapturePerUserService newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled) { - return new ContentCapturePerUserService(this, mLock, resolvedUserId); + return new ContentCapturePerUserService(this, mLock, disabled, resolvedUserId); } @Override // from SystemService @@ -178,7 +181,7 @@ public final class ContentCaptureManagerService extends synchronized (mLock) { final ContentCapturePerUserService service = getServiceForUserLocked(userId); service.startSessionLocked(activityToken, componentName, taskId, displayId, - sessionId, Binder.getCallingUid(), flags, mAllowInstantService, result); + sessionId, Binder.getCallingUid(), flags, result); } } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index 03257e3e8514..c467935f1996 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -35,6 +35,7 @@ import android.content.pm.ServiceInfo; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.service.contentcapture.ContentCaptureService; import android.service.contentcapture.SnapshotData; import android.util.ArrayMap; import android.util.Slog; @@ -42,8 +43,8 @@ import android.view.contentcapture.ContentCaptureSession; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.IResultReceiver; +import com.android.server.contentcapture.RemoteContentCaptureService.ContentCaptureServiceCallbacks; import com.android.server.infra.AbstractPerUserSystemService; -import com.android.server.infra.FrameworkResourcesServiceNameResolver; import java.io.PrintWriter; import java.util.ArrayList; @@ -53,7 +54,8 @@ import java.util.ArrayList; */ final class ContentCapturePerUserService extends - AbstractPerUserSystemService<ContentCapturePerUserService, ContentCaptureManagerService> { + AbstractPerUserSystemService<ContentCapturePerUserService, ContentCaptureManagerService> + implements ContentCaptureServiceCallbacks { private static final String TAG = ContentCaptureManagerService.class.getSimpleName(); @@ -61,16 +63,52 @@ final class ContentCapturePerUserService private final ArrayMap<String, ContentCaptureServerSession> mSessions = new ArrayMap<>(); + /** + * Reference to the remote service. + * + * <p>It's set in the constructor, but it's also updated when the service's updated in the + * master's cache (for example, because a temporary service was set). + */ + @GuardedBy("mLock") + private RemoteContentCaptureService mRemoteService; + // TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's - protected ContentCapturePerUserService( - ContentCaptureManagerService master, Object lock, @UserIdInt int userId) { - super(master, new FrameworkResourcesServiceNameResolver(master.getContext(), userId, lock, - com.android.internal.R.string.config_defaultContentCaptureService), lock, userId); + ContentCapturePerUserService(@NonNull ContentCaptureManagerService master, + @NonNull Object lock, boolean disabled, @UserIdInt int userId) { + super(master, lock, userId); + + updateRemoteServiceLocked(disabled); + } + + /** + * Updates the reference to the remote service. + */ + private void updateRemoteServiceLocked(boolean disabled) { + if (mRemoteService != null) { + if (mMaster.debug) Slog.d(TAG, "updateRemoteService(): destroying old remote service"); + mRemoteService.destroy(); + mRemoteService = null; + } + + // Updates the component name + final ComponentName serviceComponentName = updateServiceInfoLocked(); + + if (serviceComponentName == null) { + Slog.w(TAG, "updateRemoteService(): no service componennt name"); + return; + } + + if (!disabled) { + mRemoteService = new RemoteContentCaptureService( + mMaster.getContext(), + ContentCaptureService.SERVICE_INTERFACE, serviceComponentName, mUserId, this, + mMaster.isBindInstantServiceAllowed(), mMaster.verbose); + } } @Override // from PerUserSystemService - protected ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent) + protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent) throws NameNotFoundException { int flags = PackageManager.GET_META_DATA; @@ -105,14 +143,24 @@ final class ContentCapturePerUserService @GuardedBy("mLock") protected boolean updateLocked(boolean disabled) { destroyLocked(); - return super.updateLocked(disabled); + final boolean disabledStateChanged = super.updateLocked(disabled); + updateRemoteServiceLocked(disabled); + return disabledStateChanged; + } + + @Override // from ContentCaptureServiceCallbacks + public void onServiceDied(@NonNull RemoteContentCaptureService service) { + if (mMaster.debug) Slog.d(TAG, "remote service died: " + service); + synchronized (mLock) { + removeSelfFromCacheLocked(); + } } - // TODO(b/111276913): log metrics + // TODO(b/119613670): log metrics @GuardedBy("mLock") public void startSessionLocked(@NonNull IBinder activityToken, @NonNull ComponentName componentName, int taskId, int displayId, - @NonNull String sessionId, int uid, int flags, boolean bindInstantServiceAllowed, + @NonNull String sessionId, int uid, int flags, @NonNull IResultReceiver clientReceiver) { if (!isEnabledLocked()) { setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED, /* binder=*/ null); @@ -138,10 +186,23 @@ final class ContentCapturePerUserService return; } - final ContentCaptureServerSession newSession = new ContentCaptureServerSession(getContext(), - mUserId, mLock, activityToken, this, serviceComponentName, componentName, taskId, - displayId, sessionId, uid, flags, bindInstantServiceAllowed, - mMaster.verbose); + if (mRemoteService == null) { + updateRemoteServiceLocked(/* disabled= */ false); // already checked for isEnabled + } + + if (mRemoteService == null) { + // TODO(b/119613670): log metrics + Slog.w(TAG, "startSession(id=" + existingSession + ", token=" + activityToken + + ": ignoring because service is not set"); + // TODO(b/111276913): use a new disabled state? + setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED, + /* binder=*/ null); + return; + } + + final ContentCaptureServerSession newSession = new ContentCaptureServerSession( + activityToken, this, mRemoteService, componentName, taskId, + displayId, sessionId, uid, flags); if (mMaster.verbose) { Slog.v(TAG, "startSession(): new session for " + ComponentName.flattenToShortString(componentName) + " and id " + sessionId); @@ -150,7 +211,7 @@ final class ContentCapturePerUserService newSession.notifySessionStartedLocked(clientReceiver); } - // TODO(b/111276913): log metrics + // TODO(b/119613670): log metrics @GuardedBy("mLock") public void finishSessionLocked(@NonNull String sessionId) { if (!isEnabledLocked()) { @@ -241,12 +302,18 @@ final class ContentCapturePerUserService @Override protected void dumpLocked(String prefix, PrintWriter pw) { super.dumpLocked(prefix, pw); + + final String prefix2 = prefix + " "; + if (mRemoteService != null) { + pw.print(prefix); pw.println("remote service:"); + mRemoteService.dump(prefix2, pw); + } + if (mSessions.isEmpty()) { pw.print(prefix); pw.println("no sessions"); } else { final int size = mSessions.size(); pw.print(prefix); pw.print("number sessions: "); pw.println(size); - final String prefix2 = prefix + " "; for (int i = 0; i < size; i++) { pw.print(prefix); pw.print("session@"); pw.println(i); final ContentCaptureServerSession session = mSessions.valueAt(i); diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java index f59636b92278..ebe0083b398e 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java @@ -17,7 +17,6 @@ package com.android.server.contentcapture; import android.annotation.NonNull; import android.content.ComponentName; -import android.content.Context; import android.os.IBinder; import android.service.contentcapture.ContentCaptureService; import android.service.contentcapture.SnapshotData; @@ -28,15 +27,13 @@ import android.view.contentcapture.ContentCaptureSessionId; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.IResultReceiver; import com.android.internal.util.Preconditions; -import com.android.server.contentcapture.RemoteContentCaptureService.ContentCaptureServiceCallbacks; import java.io.PrintWriter; -final class ContentCaptureServerSession implements ContentCaptureServiceCallbacks { +final class ContentCaptureServerSession { private static final String TAG = ContentCaptureServerSession.class.getSimpleName(); - private final Object mLock; final IBinder mActivityToken; private final ContentCapturePerUserService mService; private final RemoteContentCaptureService mRemoteService; @@ -52,19 +49,16 @@ final class ContentCaptureServerSession implements ContentCaptureServiceCallback */ private final int mUid; - ContentCaptureServerSession(@NonNull Context context, int userId, @NonNull Object lock, - @NonNull IBinder activityToken, @NonNull ContentCapturePerUserService service, - @NonNull ComponentName serviceComponentName, @NonNull ComponentName appComponentName, - int taskId, int displayId, @NonNull String sessionId, int uid, int flags, - boolean bindInstantServiceAllowed, boolean verbose) { - mLock = lock; + ContentCaptureServerSession(@NonNull IBinder activityToken, + @NonNull ContentCapturePerUserService service, + @NonNull RemoteContentCaptureService remoteService, + @NonNull ComponentName appComponentName, + int taskId, int displayId, @NonNull String sessionId, int uid, int flags) { mActivityToken = activityToken; mService = service; mId = Preconditions.checkNotNull(sessionId); mUid = uid; - mRemoteService = new RemoteContentCaptureService(context, - ContentCaptureService.SERVICE_INTERFACE, serviceComponentName, userId, this, - bindInstantServiceAllowed, verbose); + mRemoteService = remoteService; mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null, appComponentName, taskId, displayId, flags); } @@ -126,17 +120,6 @@ final class ContentCaptureServerSession implements ContentCaptureServiceCallback } } - @Override // from RemoteContentCaptureServiceCallbacks - public void onServiceDied(@NonNull RemoteContentCaptureService service) { - // TODO(b/111276913): implement (remove session from PerUserSession?) - if (mService.isDebug()) { - Slog.d(TAG, "onServiceDied() for " + mId); - } - synchronized (mLock) { - removeSelfLocked(/* notifyRemoteService= */ true); - } - } - @GuardedBy("mLock") public void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) { pw.print(prefix); pw.print("id: "); pw.print(mId); pw.println(); diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java index 942ee11aa481..824162868e19 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java @@ -23,6 +23,7 @@ import android.os.IBinder; import android.service.contentcapture.IContentCaptureService; import android.service.contentcapture.SnapshotData; import android.text.format.DateUtils; +import android.util.Slog; import android.view.contentcapture.ContentCaptureContext; import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService; @@ -32,8 +33,6 @@ final class RemoteContentCaptureService extends AbstractMultiplePendingRequestsRemoteService<RemoteContentCaptureService, IContentCaptureService> { - // TODO(b/117779333): changed it so it's permanentely bound - private static final long TIMEOUT_IDLE_BIND_MILLIS = 2 * DateUtils.MINUTE_IN_MILLIS; private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS; RemoteContentCaptureService(Context context, String serviceInterface, @@ -42,26 +41,40 @@ final class RemoteContentCaptureService boolean verbose) { super(context, serviceInterface, componentName, userId, callbacks, bindInstantServiceAllowed, verbose, /* initialCapacity= */ 2); + + // Bind right away, which will trigger a onConnected() on service's + scheduleBind(); } - @Override // from RemoteService + @Override // from AbstractRemoteService protected IContentCaptureService getServiceInterface(@NonNull IBinder service) { return IContentCaptureService.Stub.asInterface(service); } - // TODO(b/111276913): modify super class to allow permanent binding when value is 0 or negative - @Override // from RemoteService + @Override // from AbstractRemoteService protected long getTimeoutIdleBindMillis() { // TODO(b/111276913): read from Settings so it can be changed in the field - return TIMEOUT_IDLE_BIND_MILLIS; + return PERMANENT_BOUND_TIMEOUT_MS; } - @Override // from RemoteService + @Override // from AbstractRemoteService protected long getRemoteRequestMillis() { // TODO(b/111276913): read from Settings so it can be changed in the field return TIMEOUT_REMOTE_REQUEST_MILLIS; } + @Override // from RemoteService + protected void handleOnConnectedStateChanged(boolean state) { + if (state && getTimeoutIdleBindMillis() != PERMANENT_BOUND_TIMEOUT_MS) { + scheduleUnbind(); + } + try { + mService.onConnectedStateChanged(state); + } catch (Exception e) { + Slog.w(mTag, "Exception calling onConnectedStateChanged(" + state + "): " + e); + } + } + /** * 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/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 08cb7a2f5047..121a830f05f5 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -87,6 +87,10 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; +import com.android.server.deviceidle.ConstraintController; +import com.android.server.deviceidle.DeviceIdleConstraintTracker; +import com.android.server.deviceidle.IDeviceIdleConstraint; +import com.android.server.deviceidle.TvConstraintController; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; @@ -104,6 +108,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.stream.Collectors; /** * Keeps track of device idleness and drives low power mode based on that. @@ -296,6 +301,17 @@ public class DeviceIdleController extends SystemService private Location mLastGpsLocation; // Current locked state of the screen private boolean mScreenLocked; + private int mNumBlockingConstraints = 0; + + /** + * Constraints are the "handbrakes" that stop the device from moving into a lower state until + * every one is released at the same time. + * + * @see #registerDeviceIdleConstraintInternal(IDeviceIdleConstraint, String, int) + */ + private final ArrayMap<IDeviceIdleConstraint, DeviceIdleConstraintTracker> + mConstraints = new ArrayMap<>(); + private ConstraintController mConstraintController; /** Device is currently active. */ @VisibleForTesting @@ -703,8 +719,7 @@ public class DeviceIdleController extends SystemService * global Settings. Any access to this class or its fields should be done while * holding the DeviceIdleController lock. */ - @VisibleForTesting - final class Constants extends ContentObserver { + public final class Constants extends ContentObserver { // Key names stored in the settings value. private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = "light_after_inactive_to"; @@ -1031,9 +1046,9 @@ public class DeviceIdleController extends SystemService INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_INACTIVE_TIMEOUT, !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10)); SENSING_TIMEOUT = mParser.getDurationMillis(KEY_SENSING_TIMEOUT, - !DEBUG ? 4 * 60 * 1000L : 60 * 1000L); + !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L); LOCATING_TIMEOUT = mParser.getDurationMillis(KEY_LOCATING_TIMEOUT, - !DEBUG ? 30 * 1000L : 15 * 1000L); + !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L); LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20); MOTION_INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_MOTION_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); @@ -1228,6 +1243,7 @@ public class DeviceIdleController extends SystemService private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7; private static final int MSG_FINISH_IDLE_OP = 8; private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9; + private static final int MSG_SEND_CONSTRAINT_MONITORING = 10; final class MyHandler extends Handler { MyHandler(Looper looper) { @@ -1348,6 +1364,15 @@ public class DeviceIdleController extends SystemService final boolean added = (msg.arg2 == 1); mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, added); } break; + case MSG_SEND_CONSTRAINT_MONITORING: { + final IDeviceIdleConstraint constraint = (IDeviceIdleConstraint) msg.obj; + final boolean monitoring = (msg.arg1 == 1); + if (monitoring) { + constraint.startMonitoring(); + } else { + constraint.stopMonitoring(); + } + } break; } } } @@ -1512,6 +1537,25 @@ public class DeviceIdleController extends SystemService } public class LocalService { + public void onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active) { + synchronized (DeviceIdleController.this) { + onConstraintStateChangedLocked(constraint, active); + } + } + + public void registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name, + @IDeviceIdleConstraint.MinimumState int minState) { + registerDeviceIdleConstraintInternal(constraint, name, minState); + } + + public void unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint) { + unregisterDeviceIdleConstraintInternal(constraint); + } + + public void exitIdle(String reason) { + exitIdleInternal(reason); + } + // duration in milliseconds public void addPowerSaveTempWhitelistApp(int callingUid, String packageName, long duration, int userId, boolean sync, String reason) { @@ -1562,6 +1606,7 @@ public class DeviceIdleController extends SystemService static class Injector { private final Context mContext; private ConnectivityService mConnectivityService; + private Constants mConstants; private LocationManager mLocationManager; Injector(Context ctx) { @@ -1591,7 +1636,10 @@ public class DeviceIdleController extends SystemService Constants getConstants(DeviceIdleController controller, Handler handler, ContentResolver resolver) { - return controller.new Constants(handler, resolver); + if (mConstants == null) { + mConstants = controller.new Constants(handler, resolver); + } + return mConstants; } LocationManager getLocationManager() { @@ -1608,6 +1656,23 @@ public class DeviceIdleController extends SystemService PowerManager getPowerManager() { return mContext.getSystemService(PowerManager.class); } + + SensorManager getSensorManager() { + return mContext.getSystemService(SensorManager.class); + } + + ConstraintController getConstraintController(Handler handler, LocalService localService) { + if (mContext.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) { + return new TvConstraintController(mContext, handler); + } + return null; + } + + boolean useMotionSensor() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_autoPowerModeUseMotionSensor); + } } private final Injector mInjector; @@ -1632,9 +1697,7 @@ public class DeviceIdleController extends SystemService mHandler = mInjector.getHandler(this); mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper()); LocalServices.addService(AppStateTracker.class, mAppStateTracker); - - mUseMotionSensor = context.getResources().getBoolean( - com.android.internal.R.bool.config_autoPowerModeUseMotionSensor); + mUseMotionSensor = mInjector.useMotionSensor(); } public DeviceIdleController(Context context) { @@ -1734,7 +1797,7 @@ public class DeviceIdleController extends SystemService mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class); - mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); + mSensorManager = mInjector.getSensorManager(); if (mUseMotionSensor) { int sigMotionSensorId = getContext().getResources().getInteger( @@ -1763,6 +1826,12 @@ public class DeviceIdleController extends SystemService .setNumUpdates(1); } + mConstraintController = mInjector.getConstraintController( + mHandler, getLocalService(LocalService.class)); + if (mConstraintController != null) { + mConstraintController.start(); + } + float angleThreshold = getContext().getResources().getInteger( com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f; mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this, @@ -1818,6 +1887,99 @@ public class DeviceIdleController extends SystemService } } + @VisibleForTesting + boolean hasMotionSensor() { + return mUseMotionSensor && mMotionSensor != null; + } + + private void registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint, + final String name, final int type) { + final int minState; + switch (type) { + case IDeviceIdleConstraint.ACTIVE: + minState = STATE_ACTIVE; + break; + case IDeviceIdleConstraint.SENSING_OR_ABOVE: + minState = STATE_SENSING; + break; + default: + Slog.wtf(TAG, "Registering device-idle constraint with invalid type: " + type); + return; + } + synchronized (this) { + if (mConstraints.containsKey(constraint)) { + Slog.e(TAG, "Re-registering device-idle constraint: " + constraint + "."); + return; + } + DeviceIdleConstraintTracker tracker = new DeviceIdleConstraintTracker(name, minState); + mConstraints.put(constraint, tracker); + updateActiveConstraintsLocked(); + } + } + + private void unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint) { + synchronized (this) { + // Artifically force the constraint to inactive to unblock anything waiting for it. + onConstraintStateChangedLocked(constraint, /* active= */ false); + + // Let the constraint know that we are not listening to it any more. + setConstraintMonitoringLocked(constraint, /* monitoring= */ false); + mConstraints.remove(constraint); + } + } + + @GuardedBy("this") + private void onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active) { + DeviceIdleConstraintTracker tracker = mConstraints.get(constraint); + if (tracker == null) { + Slog.e(TAG, "device-idle constraint " + constraint + " has not been registered."); + return; + } + if (active != tracker.active && tracker.monitoring) { + tracker.active = active; + mNumBlockingConstraints += (tracker.active ? +1 : -1); + if (mNumBlockingConstraints == 0) { + if (mState == STATE_ACTIVE) { + becomeInactiveIfAppropriateLocked(); + } else if (mNextAlarmTime == 0 || mNextAlarmTime < SystemClock.elapsedRealtime()) { + stepIdleStateLocked("s:" + tracker.name); + } + } + } + } + + @GuardedBy("this") + private void setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor) { + DeviceIdleConstraintTracker tracker = mConstraints.get(constraint); + if (tracker.monitoring != monitor) { + tracker.monitoring = monitor; + updateActiveConstraintsLocked(); + // We send the callback on a separate thread instead of just relying on oneway as + // the client could be in the system server with us and cause re-entry problems. + mHandler.obtainMessage(MSG_SEND_CONSTRAINT_MONITORING, + /* monitoring= */ monitor ? 1 : 0, + /* <not used>= */ -1, + /* constraint= */ constraint).sendToTarget(); + } + } + + @GuardedBy("this") + private void updateActiveConstraintsLocked() { + mNumBlockingConstraints = 0; + for (int i = 0; i < mConstraints.size(); i++) { + final IDeviceIdleConstraint constraint = mConstraints.keyAt(i); + final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i); + final boolean monitoring = (tracker.minState == mState); + if (monitoring != tracker.monitoring) { + setConstraintMonitoringLocked(constraint, monitoring); + tracker.active = monitoring; + } + if (tracker.monitoring && tracker.active) { + mNumBlockingConstraints++; + } + } + } + public boolean addPowerSaveWhitelistAppInternal(String name) { synchronized (this) { try { @@ -2448,6 +2610,7 @@ public class DeviceIdleController extends SystemService cancelLocatingLocked(); stopMonitoringMotionLocked(); mAnyMotionDetector.stop(); + updateActiveConstraintsLocked(); } private void resetLightIdleManagementLocked() { @@ -2583,40 +2746,50 @@ public class DeviceIdleController extends SystemService return; } + if (mNumBlockingConstraints != 0 && !mForceIdle) { + // We have some constraints from other parts of the system server preventing + // us from moving to the next state. + if (DEBUG) { + Slog.i(TAG, "Cannot step idle state. Blocked by: " + mConstraints.values().stream() + .filter(x -> x.active) + .map(x -> x.name) + .collect(Collectors.joining(","))); + } + return; + } + switch (mState) { case STATE_INACTIVE: // We have now been inactive long enough, it is time to start looking // for motion and sleep some more while doing so. startMonitoringMotionLocked(); scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false); - mState = STATE_IDLE_PENDING; - if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING."); - EventLogTags.writeDeviceIdle(mState, reason); + moveToStateLocked(STATE_IDLE_PENDING, reason); break; case STATE_IDLE_PENDING: - mState = STATE_SENSING; - if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); - EventLogTags.writeDeviceIdle(mState, reason); + moveToStateLocked(STATE_SENSING, reason); cancelLocatingLocked(); mLocated = false; mLastGenericLocation = null; mLastGpsLocation = null; + updateActiveConstraintsLocked(); - // If we have an accelerometer, wait to find out whether we are moving. + // Wait for open constraints and an accelerometer reading before moving on. if (mUseMotionSensor && mAnyMotionDetector.hasSensor()) { scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT); mNotMoving = false; mAnyMotionDetector.checkForAnyMotion(); break; + } else if (mNumBlockingConstraints != 0) { + cancelAlarmLocked(); + break; } mNotMoving = true; // Otherwise, fall through and check this off the list of requirements. case STATE_SENSING: cancelSensingTimeoutAlarmLocked(); - mState = STATE_LOCATING; - if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); - EventLogTags.writeDeviceIdle(mState, reason); + moveToStateLocked(STATE_LOCATING, reason); scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false); LocationManager locationManager = mInjector.getLocationManager(); if (locationManager != null @@ -2665,12 +2838,11 @@ public class DeviceIdleController extends SystemService if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) { mNextIdleDelay = mConstants.IDLE_TIMEOUT; } - mState = STATE_IDLE; + moveToStateLocked(STATE_IDLE, reason); if (mLightState != LIGHT_STATE_OVERRIDE) { mLightState = LIGHT_STATE_OVERRIDE; cancelLightAlarmLocked(); } - EventLogTags.writeDeviceIdle(mState, reason); addEvent(EVENT_DEEP_IDLE, null); mGoingIdleWakeLock.acquire(); mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); @@ -2688,14 +2860,24 @@ public class DeviceIdleController extends SystemService if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) { mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; } - mState = STATE_IDLE_MAINTENANCE; - EventLogTags.writeDeviceIdle(mState, reason); + moveToStateLocked(STATE_IDLE_MAINTENANCE, reason); addEvent(EVENT_DEEP_MAINTENANCE, null); mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); break; } } + private void moveToStateLocked(int state, String reason) { + final int oldState = mState; + mState = state; + if (DEBUG) { + Slog.d(TAG, String.format("Moved from STATE_%s to STATE_%s.", + stateToString(oldState), stateToString(mState))); + } + EventLogTags.writeDeviceIdle(mState, reason); + updateActiveConstraintsLocked(); + } + void incActiveIdleOps() { synchronized (this) { mActiveIdleOpCount++; @@ -2818,6 +3000,7 @@ public class DeviceIdleController extends SystemService mMaintenanceStartTime = 0; EventLogTags.writeDeviceIdle(mState, type); becomeInactive = true; + updateActiveConstraintsLocked(); } if (mLightState == LIGHT_STATE_OVERRIDE) { // We went out of light idle mode because we had started deep idle mode... let's @@ -3794,8 +3977,22 @@ public class DeviceIdleController extends SystemService pw.print(" mScreenLocked="); pw.println(mScreenLocked); pw.print(" mNetworkConnected="); pw.println(mNetworkConnected); pw.print(" mCharging="); pw.println(mCharging); - pw.print(" mMotionActive="); pw.println(mMotionListener.active); + if (mConstraints.size() != 0) { + pw.println(" mConstraints={"); + for (int i = 0; i < mConstraints.size(); i++) { + final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i); + pw.print(" \""); pw.print(tracker.name); pw.print("\"="); + if (tracker.minState == mState) { + pw.println(tracker.active); + } else { + pw.print("ignored <mMinState="); pw.print(stateToString(tracker.minState)); + pw.println(">"); + } + } + pw.println(" }"); + } if (mUseMotionSensor) { + pw.print(" mMotionActive="); pw.println(mMotionListener.active); pw.print(" mNotMoving="); pw.println(mNotMoving); } pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps="); diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java new file mode 100644 index 000000000000..06dc9188d1ee --- /dev/null +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -0,0 +1,572 @@ +/* + * 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.server; + +import android.content.Context; +import android.os.Environment; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.os.Process; +import android.os.SystemClock; +import android.text.TextUtils; +import android.util.ArrayMap; +import android.util.AtomicFile; +import android.util.Log; +import android.util.Slog; +import android.util.Xml; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.FastXmlSerializer; +import com.android.internal.util.XmlUtils; + +import libcore.io.IoUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * Monitors the health of packages on the system and notifies interested observers when packages + * fail. All registered observers will be notified until an observer takes a mitigation action. + */ +public class PackageWatchdog { + private static final String TAG = "PackageWatchdog"; + // Duration to count package failures before it resets to 0 + private static final int TRIGGER_DURATION_MS = 60000; + // Number of package failures within the duration above before we notify observers + private static final int TRIGGER_FAILURE_COUNT = 5; + private static final int DB_VERSION = 1; + private static final String TAG_PACKAGE_WATCHDOG = "package-watchdog"; + private static final String TAG_PACKAGE = "package"; + private static final String TAG_OBSERVER = "observer"; + private static final String ATTR_VERSION = "version"; + private static final String ATTR_NAME = "name"; + private static final String ATTR_DURATION = "duration"; + private static final int MESSAGE_SAVE_FILE = 1; + + private static PackageWatchdog sPackageWatchdog; + + private final Object mLock = new Object(); + // System server context + private final Context mContext; + // Handler to run package cleanup runnables + private final Handler mTimerHandler; + private final HandlerThread mIoThread = new HandlerThread("package_watchdog_io", + Process.THREAD_PRIORITY_BACKGROUND); + private final Handler mIoHandler; + // Maps observer names to package observers that have been registered since the last boot + @GuardedBy("mLock") + final Map<String, PackageHealthObserver> mRegisteredObservers = new ArrayMap<>(); + // Maps observer names to internal observers (registered or not) loaded from file + @GuardedBy("mLock") + final Map<String, ObserverInternal> mAllObservers = new ArrayMap<>(); + // /data/system/ directory + private final File mSystemDir = new File(Environment.getDataDirectory(), "system"); + // File containing the XML data of monitored packages + private final AtomicFile mPolicyFile = + new AtomicFile(new File(mSystemDir, "package-watchdog.xml")); + // Runnable to prune monitored packages that have expired + private final Runnable mPackageCleanup; + // Last SystemClock#uptimeMillis a package clean up was executed. + // 0 if mPackageCleanup not running. + private long mUptimeAtLastRescheduleMs; + // Duration a package cleanup was last scheduled for. + // 0 if mPackageCleanup not running. + private long mDurationAtLastReschedule; + + private PackageWatchdog(Context context) { + mContext = context; + mTimerHandler = new Handler(Looper.myLooper()); + mIoThread.start(); + mIoHandler = new IoHandler(mIoThread.getLooper()); + mPackageCleanup = this::rescheduleCleanup; + loadFromFile(); + } + + /** Creates or gets singleton instance of PackageWatchdog. */ + public static synchronized PackageWatchdog getInstance(Context context) { + if (sPackageWatchdog == null) { + sPackageWatchdog = new PackageWatchdog(context); + } + return sPackageWatchdog; + } + + /** + * Registers {@code observer} to listen for package failures + * + * <p>Observers are expected to call this on boot. It does not specify any packages but + * it will resume observing any packages requested from a previous boot. + */ + public void registerHealthObserver(PackageHealthObserver observer) { + synchronized (mLock) { + mRegisteredObservers.put(observer.getName(), observer); + if (mDurationAtLastReschedule == 0) { + // Nothing running, schedule + rescheduleCleanup(); + } + } + } + + /** + * Starts observing the health of the {@code packages} for {@code observer} and notifies + * {@code observer} of any package failures within the monitoring duration. + * + * <p>If {@code observer} is already monitoring a package in {@code packageNames}, + * the monitoring window of that package will be reset to {@code hours}. + * + * @throws IllegalArgumentException if {@code packageNames} is empty + * or {@code hours} is less than 1 + */ + public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames, + int hours) { + if (packageNames.isEmpty() || hours < 1) { + throw new IllegalArgumentException("Observation not started, no packages specified" + + "or invalid hours"); + } + long durationMs = TimeUnit.HOURS.toMillis(hours); + List<MonitoredPackage> packages = new ArrayList<>(); + for (String packageName : packageNames) { + packages.add(new MonitoredPackage(packageName, durationMs)); + } + synchronized (mLock) { + ObserverInternal oldObserver = mAllObservers.get(observer.getName()); + if (oldObserver == null) { + Slog.d(TAG, observer.getName() + " started monitoring health of packages " + + packageNames); + mAllObservers.put(observer.getName(), + new ObserverInternal(observer.getName(), packages)); + } else { + Slog.d(TAG, observer.getName() + " added the following packages to monitor " + + packageNames); + oldObserver.updatePackages(packages); + } + } + registerHealthObserver(observer); + // Always reschedule because we may need to expire packages + // earlier than we are already scheduled for + rescheduleCleanup(); + sendIoMessage(MESSAGE_SAVE_FILE); + } + + /** + * Unregisters {@code observer} from listening to package failure. + * Additionally, this stops observing any packages that may have previously been observed + * even from a previous boot. + */ + public void unregisterHealthObserver(PackageHealthObserver observer) { + synchronized (mLock) { + mAllObservers.remove(observer.getName()); + mRegisteredObservers.remove(observer.getName()); + } + sendIoMessage(MESSAGE_SAVE_FILE); + } + + // TODO(zezeozue:) Accept current versionCodes of failing packages? + /** + * Called when a process fails either due to a crash or ANR. + * + * <p>All registered observers for the packages contained in the process will be notified in + * order of priority unitl an observer signifies that it has taken action and other observers + * should not notified. + * + * <p>This method could be called frequently if there is a severe problem on the device. + */ + public void onPackageFailure(String[] packages) { + synchronized (mLock) { + if (mRegisteredObservers.isEmpty()) { + return; + } + for (String packageName : packages) { + for (ObserverInternal observer : mAllObservers.values()) { + if (observer.onPackageFailure(packageName)) { + PackageHealthObserver activeObserver = + mRegisteredObservers.get(observer.mName); + if (activeObserver != null + && activeObserver.onHealthCheckFailed(packageName)) { + // Observer has handled, do not notify other observers + break; + } + } + } + } + } + } + + // TODO(zezeozue): Optimize write? Maybe only write a separate smaller file? + // This currently adds about 7ms extra to shutdown thread + /** Writes the package information to file during shutdown. */ + public void writeNow() { + if (!mAllObservers.isEmpty()) { + mIoHandler.removeMessages(MESSAGE_SAVE_FILE); + pruneObservers(SystemClock.uptimeMillis() - mUptimeAtLastRescheduleMs); + saveToFile(); + Slog.i(TAG, "Last write to update package durations"); + } + } + + /** Register instances of this interface to receive notifications on package failure. */ + public interface PackageHealthObserver { + /** + * Called when health check fails for the {@code packages}. + * @return {@code true} if action was taken and other observers should not be notified of + * this failure, {@code false} otherwise. + */ + boolean onHealthCheckFailed(String packageName); + + // TODO(zezeozue): Ensure uniqueness? + /** + * Identifier for the observer, should not change across device updates otherwise the + * watchdog may drop observing packages with the old name. + */ + String getName(); + } + + /** Reschedules handler to prune expired packages from observers. */ + private void rescheduleCleanup() { + synchronized (mLock) { + long nextDurationToScheduleMs = getEarliestPackageExpiryLocked(); + if (nextDurationToScheduleMs == Long.MAX_VALUE) { + Slog.i(TAG, "No monitored packages, ending package cleanup"); + mDurationAtLastReschedule = 0; + mUptimeAtLastRescheduleMs = 0; + return; + } + long uptimeMs = SystemClock.uptimeMillis(); + // O if mPackageCleanup not running + long elapsedDurationMs = mUptimeAtLastRescheduleMs == 0 + ? 0 : uptimeMs - mUptimeAtLastRescheduleMs; + // O if mPackageCleanup not running + long remainingDurationMs = mDurationAtLastReschedule - elapsedDurationMs; + + if (mUptimeAtLastRescheduleMs == 0 || nextDurationToScheduleMs < remainingDurationMs) { + // First schedule or an earlier reschedule + pruneObservers(elapsedDurationMs); + mTimerHandler.removeCallbacks(mPackageCleanup); + mTimerHandler.postDelayed(mPackageCleanup, nextDurationToScheduleMs); + mDurationAtLastReschedule = nextDurationToScheduleMs; + mUptimeAtLastRescheduleMs = uptimeMs; + } + } + } + + /** + * Returns the earliest time a package should expire. + * @returns Long#MAX_VALUE if there are no observed packages. + */ + private long getEarliestPackageExpiryLocked() { + long shortestDurationMs = Long.MAX_VALUE; + for (ObserverInternal observer : mAllObservers.values()) { + for (MonitoredPackage p : observer.mPackages.values()) { + if (p.mDurationMs < shortestDurationMs) { + shortestDurationMs = p.mDurationMs; + } + } + } + Slog.v(TAG, "Earliest package time is " + shortestDurationMs); + return shortestDurationMs; + } + + /** + * Removes {@code elapsedMs} milliseconds from all durations on monitored packages. + * Discards expired packages and discards observers without any packages. + */ + private void pruneObservers(long elapsedMs) { + if (elapsedMs == 0) { + return; + } + synchronized (mLock) { + Slog.d(TAG, "Removing expired packages after " + elapsedMs + "ms"); + Iterator<ObserverInternal> it = mAllObservers.values().iterator(); + while (it.hasNext()) { + ObserverInternal observer = it.next(); + if (!observer.updateMonitoringDurations(elapsedMs)) { + Slog.i(TAG, "Discarding observer " + observer.mName + ". All packages expired"); + it.remove(); + } + } + } + sendIoMessage(MESSAGE_SAVE_FILE); + } + + /** + * Loads mAllObservers from file. + * + * <p>Note that this is <b>not</b> thread safe and should only called be called + * from the constructor. + */ + private void loadFromFile() { + InputStream infile = null; + mAllObservers.clear(); + try { + infile = mPolicyFile.openRead(); + final XmlPullParser parser = Xml.newPullParser(); + parser.setInput(infile, StandardCharsets.UTF_8.name()); + XmlUtils.beginDocument(parser, TAG_PACKAGE_WATCHDOG); + int outerDepth = parser.getDepth(); + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + ObserverInternal observer = ObserverInternal.read(parser); + if (observer != null) { + mAllObservers.put(observer.mName, observer); + } + } + } catch (FileNotFoundException e) { + // Nothing to monitor + } catch (IOException e) { + Log.wtf(TAG, "Unable to read monitored packages", e); + } catch (NumberFormatException e) { + Log.wtf(TAG, "Unable to parse monitored package windows", e); + } catch (XmlPullParserException e) { + Log.wtf(TAG, "Unable to parse monitored packages", e); + } finally { + IoUtils.closeQuietly(infile); + } + } + + /** + * Persists mAllObservers to file and ignores threshold information. + * + * <p>Note that this is <b>not</b> thread safe and should only be called on the + * single threaded IoHandler. + */ + private boolean saveToFile() { + FileOutputStream stream; + try { + stream = mPolicyFile.startWrite(); + } catch (IOException e) { + Slog.w(TAG, "Cannot update monitored packages", e); + return false; + } + + try { + XmlSerializer out = new FastXmlSerializer(); + out.setOutput(stream, StandardCharsets.UTF_8.name()); + out.startDocument(null, true); + out.startTag(null, TAG_PACKAGE_WATCHDOG); + out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION)); + for (ObserverInternal observer : mAllObservers.values()) { + observer.write(out); + } + out.endTag(null, TAG_PACKAGE_WATCHDOG); + out.endDocument(); + mPolicyFile.finishWrite(stream); + return true; + } catch (IOException e) { + Slog.w(TAG, "Failed to save monitored packages, restoring backup", e); + mPolicyFile.failWrite(stream); + return false; + } finally { + IoUtils.closeQuietly(stream); + } + } + + private void sendIoMessage(int what) { + if (!mIoHandler.hasMessages(what)) { + Message m = Message.obtain(mIoHandler, what); + mIoHandler.sendMessage(m); + } + } + + /** + * Represents an observer monitoring a set of packages along with the failure thresholds for + * each package. + */ + static class ObserverInternal { + public final String mName; + public final ArrayMap<String, MonitoredPackage> mPackages; + + ObserverInternal(String name, List<MonitoredPackage> packages) { + mName = name; + mPackages = new ArrayMap<>(); + updatePackages(packages); + } + + /** + * Writes important details to file. Doesn't persist any package failure thresholds. + * + * <p>Note that this method is <b>not</b> thread safe. It should only be called from + * #saveToFile which runs on a single threaded handler. + */ + public boolean write(XmlSerializer out) { + try { + out.startTag(null, TAG_OBSERVER); + out.attribute(null, ATTR_NAME, mName); + for (int i = 0; i < mPackages.size(); i++) { + MonitoredPackage p = mPackages.valueAt(i); + out.startTag(null, TAG_PACKAGE); + out.attribute(null, ATTR_NAME, p.mName); + out.attribute(null, ATTR_DURATION, String.valueOf(p.mDurationMs)); + out.endTag(null, TAG_PACKAGE); + } + out.endTag(null, TAG_OBSERVER); + return true; + } catch (IOException e) { + Slog.w(TAG, "Cannot save observer", e); + return false; + } + } + + public void updatePackages(List<MonitoredPackage> packages) { + synchronized (mName) { + for (MonitoredPackage p : packages) { + mPackages.put(p.mName, p); + } + } + } + + /** + * Reduces the monitoring durations of all packages observed by this observer by + * {@code elapsedMs}. If any duration is less than 0, the package is removed from + * observation. + * + * @returns {@code true} if there are still packages to be observed, {@code false} otherwise + */ + public boolean updateMonitoringDurations(long elapsedMs) { + List<MonitoredPackage> packages = new ArrayList<>(); + synchronized (mName) { + Iterator<MonitoredPackage> it = mPackages.values().iterator(); + while (it.hasNext()) { + MonitoredPackage p = it.next(); + long newDuration = p.mDurationMs - elapsedMs; + if (newDuration > 0) { + p.mDurationMs = newDuration; + } else { + it.remove(); + } + } + return !mPackages.isEmpty(); + } + } + + /** + * Increments failure counts of {@code packageName}. + * @returns {@code true} if failure threshold is exceeded, {@code false} otherwise + */ + public boolean onPackageFailure(String packageName) { + synchronized (mName) { + MonitoredPackage p = mPackages.get(packageName); + if (p != null) { + return p.onFailure(); + } + return false; + } + } + + /** + * Returns one ObserverInternal from the {@code parser} and advances its state. + * + * <p>Note that this method is <b>not</b> thread safe. It should only be called from + * #loadFromFile which in turn is only called on construction of the + * singleton PackageWatchdog. + **/ + public static ObserverInternal read(XmlPullParser parser) { + String observerName = null; + if (TAG_OBSERVER.equals(parser.getName())) { + observerName = parser.getAttributeValue(null, ATTR_NAME); + if (TextUtils.isEmpty(observerName)) { + return null; + } + } + List<MonitoredPackage> packages = new ArrayList<>(); + int innerDepth = parser.getDepth(); + try { + while (XmlUtils.nextElementWithin(parser, innerDepth)) { + if (TAG_PACKAGE.equals(parser.getName())) { + String packageName = parser.getAttributeValue(null, ATTR_NAME); + long duration = Long.parseLong( + parser.getAttributeValue(null, ATTR_DURATION)); + if (!TextUtils.isEmpty(packageName)) { + packages.add(new MonitoredPackage(packageName, duration)); + } + } + } + } catch (IOException e) { + return null; + } catch (XmlPullParserException e) { + return null; + } + if (packages.isEmpty()) { + return null; + } + return new ObserverInternal(observerName, packages); + } + } + + /** Represents a package along with the time it should be monitored for. */ + static class MonitoredPackage { + public final String mName; + // System uptime duration to monitor package + public long mDurationMs; + // System uptime of first package failure + private long mUptimeStartMs; + // Number of failures since mUptimeStartMs + private int mFailures; + + MonitoredPackage(String name, long durationMs) { + mName = name; + mDurationMs = durationMs; + } + + /** + * Increment package failures or resets failure count depending on the last package failure. + * + * @return {@code true} if failure count exceeds a threshold, {@code false} otherwise + */ + public synchronized boolean onFailure() { + final long now = SystemClock.uptimeMillis(); + final long duration = now - mUptimeStartMs; + if (duration > TRIGGER_DURATION_MS) { + // TODO(zezeozue): Reseting to 1 is not correct + // because there may be more than 1 failure in the last trigger window from now + // This is the RescueParty impl, will leave for now + mFailures = 1; + mUptimeStartMs = now; + } else { + mFailures++; + } + return mFailures >= TRIGGER_FAILURE_COUNT; + } + } + + private class IoHandler extends Handler { + IoHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_SAVE_FILE: + saveToFile(); + break; + } + } + } +} diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index e80e9e1b594e..1aeb6898fa13 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -91,6 +91,7 @@ public class Watchdog extends Thread { "/system/bin/mediaserver", "/system/bin/sdcard", "/system/bin/surfaceflinger", + "/system/bin/vold", "media.extractor", // system/bin/mediaextractor "media.metrics", // system/bin/mediametrics "media.codec", // vendor/bin/hw/android.hardware.media.omx@1.0-service diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1a5dd90b918a..16c236ef83ad 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -336,6 +336,7 @@ import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.LockGuard; import com.android.server.NetworkManagementInternal; +import com.android.server.PackageWatchdog; import com.android.server.RescueParty; import com.android.server.ServiceThread; import com.android.server.SystemConfig; @@ -587,6 +588,7 @@ public class ActivityManagerService extends IActivityManager.Stub public final PendingIntentController mPendingIntentController; final AppErrors mAppErrors; + final PackageWatchdog mPackageWatchdog; /** * Indicates the maximum time spent waiting for the network rules to get updated. @@ -2209,6 +2211,7 @@ public class ActivityManagerService extends IActivityManager.Stub mContext = mInjector.getContext(); mUiContext = null; mAppErrors = null; + mPackageWatchdog = null; mActiveUids = new ActiveUids(this, false /* postChangesToAtm */); mAppOpsService = mInjector.getAppOpsService(null /* file */, null /* handler */); mBatteryStatsService = null; @@ -2275,7 +2278,8 @@ public class ActivityManagerService extends IActivityManager.Stub mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); - mAppErrors = new AppErrors(mUiContext, this); + mPackageWatchdog = PackageWatchdog.getInstance(mUiContext); + mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog); mActiveUids = new ActiveUids(this, true /* postChangesToAtm */); final File systemDir = SystemServiceManager.ensureSystemDir(); diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 1c1daffceafe..a634b577f506 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -53,6 +53,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.app.ProcessMap; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; +import com.android.server.PackageWatchdog; import com.android.server.RescueParty; import com.android.server.wm.WindowProcessController; @@ -69,6 +70,7 @@ class AppErrors { private final ActivityManagerService mService; private final Context mContext; + private final PackageWatchdog mPackageWatchdog; private ArraySet<String> mAppsNotReportingCrashes; @@ -93,10 +95,11 @@ class AppErrors { private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>(); - AppErrors(Context context, ActivityManagerService service) { + AppErrors(Context context, ActivityManagerService service, PackageWatchdog watchdog) { context.assertRuntimeOverlayThemable(); mService = service; mContext = context; + mPackageWatchdog = watchdog; } void writeToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) { @@ -400,10 +403,16 @@ class AppErrors { longMsg = shortMsg; } - // If a persistent app is stuck in a crash loop, the device isn't very - // usable, so we want to consider sending out a rescue party. - if (r != null && r.isPersistent()) { - RescueParty.notePersistentAppCrash(mContext, r.uid); + if (r != null) { + if (r.isPersistent()) { + // If a persistent app is stuck in a crash loop, the device isn't very + // usable, so we want to consider sending out a rescue party. + RescueParty.notePersistentAppCrash(mContext, r.uid); + } else { + // If a non-persistent app is stuck in crash loop, we want to inform + // the package watchdog, maybe an update or experiment can be rolled back. + mPackageWatchdog.onPackageFailure(r.getPackageList()); + } } final int relaunchReason = r != null @@ -821,6 +830,7 @@ class AppErrors { void handleShowAnrUi(Message msg) { Dialog dialogToShow = null; + String[] packageList = null; synchronized (mService) { AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj; final ProcessRecord proc = data.proc; @@ -828,6 +838,9 @@ class AppErrors { Slog.e(TAG, "handleShowAnrUi: proc is null"); return; } + if (!proc.isPersistent()) { + packageList = proc.getPackageList(); + } if (proc.anrDialog != null) { Slog.e(TAG, "App already has anr dialog: " + proc); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, @@ -851,6 +864,10 @@ class AppErrors { if (dialogToShow != null) { dialogToShow.show(); } + // Notify PackageWatchdog without the lock held + if (packageList != null) { + mPackageWatchdog.onPackageFailure(packageList); + } } /** diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 117984e10cf5..d133deaf4b8e 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1362,8 +1362,9 @@ public final class ProcessList { mService.mNativeDebuggingApp = null; } - if (app.info.isPrivilegedApp() && - DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet())) { + if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY) != 0 + || (app.info.isPrivilegedApp() + && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) { runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; } @@ -1613,6 +1614,13 @@ public final class ProcessList { app.addPackage(info.packageName, info.versionCode, mService.mProcessStats); checkSlow(startTime, "startProcess: done, added package to proc"); return app; + } else if (app.getActiveInstrumentation() != null) { + // We don't want to kill running instrumentation. + if (DEBUG_PROCESSES) { + Slog.v(TAG_PROCESSES, "Instrumentation already running: " + app); + } + checkSlow(startTime, "startProcess: keep instrumentation proc"); + return app; } // An application record is attached to a previous process, diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 6cde4adb9f11..d704a3ea8eb1 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -7822,6 +7822,36 @@ public class AudioService extends IAudioService.Stub return AudioManager.SUCCESS; } + /** see AudioPolicy.setUidDeviceAffinity() */ + public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, + @NonNull int[] deviceTypes, + @NonNull String[] deviceAddresses) { + synchronized (mAudioPolicies) { + final AudioPolicyProxy app = + checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); + if (app == null) { + return AudioManager.ERROR; + } + if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { + return AudioManager.ERROR; + } + } + return AudioManager.SUCCESS; + } + + /** see AudioPolicy.removeUidDeviceAffinity() */ + public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { + synchronized (mAudioPolicies) { + final AudioPolicyProxy app = + checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); + if (app == null) { + return AudioManager.ERROR; + } + + } + return AudioManager.SUCCESS; + } + public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior + " policy " + pcb.asBinder()); @@ -7994,6 +8024,15 @@ public class AudioService extends IAudioService.Stub //====================== // Audio policy proxy //====================== + private static final class AudioDeviceArray { + final @NonNull int[] mDeviceTypes; + final @NonNull String[] mDeviceAddresses; + AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { + mDeviceTypes = types; + mDeviceAddresses = addresses; + } + } + /** * This internal class inherits from AudioPolicyConfig, each instance contains all the * mixes of an AudioPolicy and their configurations. @@ -8003,6 +8042,8 @@ public class AudioService extends IAudioService.Stub final IAudioPolicyCallback mPolicyCallback; final boolean mHasFocusListener; final boolean mIsVolumeController; + final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = + new HashMap<Integer, AudioDeviceArray>(); /** * Audio focus ducking behavior for an audio policy. * This variable reflects the value that was successfully set in @@ -8075,6 +8116,26 @@ public class AudioService extends IAudioService.Stub return false; } + // Verify all the devices in the array are served by mixes defined in this policy + boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, + @NonNull String[] deviceAddresses) { + for (int i = 0; i < deviceTypes.length; i++) { + boolean hasDevice = false; + for (AudioMix mix : mMixes) { + // this will check both that the mix has ROUTE_FLAG_RENDER and the device + // is reached by this mix + if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { + hasDevice = true; + break; + } + } + if (!hasDevice) { + return false; + } + } + return true; + } + void addMixes(@NonNull ArrayList<AudioMix> mixes) { // TODO optimize to not have to unregister the mixes already in place synchronized (mMixes) { @@ -8098,6 +8159,29 @@ public class AudioService extends IAudioService.Stub AudioSystem.registerPolicyMixes(mMixes, true); Binder.restoreCallingIdentity(identity); } + + void setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { + final Integer Uid = new Integer(uid); + if (mUidDeviceAffinities.remove(Uid) != null) { + final long identity = Binder.clearCallingIdentity(); + AudioSystem.removeUidDeviceAffinities(uid); + Binder.restoreCallingIdentity(identity); + } + final long identity = Binder.clearCallingIdentity(); + final int res = AudioSystem.setUidDeviceAffinities(uid, types, addresses); + Binder.restoreCallingIdentity(identity); + if (res == AudioSystem.SUCCESS) { + mUidDeviceAffinities.put(Uid, new AudioDeviceArray(types, addresses)); + } + } + + void removeUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { + if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { + final long identity = Binder.clearCallingIdentity(); + AudioSystem.removeUidDeviceAffinities(uid); + Binder.restoreCallingIdentity(identity); + } + } }; //====================== diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index bf95210195b7..9684f4c4ae19 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -944,6 +944,10 @@ public class NetworkMonitor extends StateMachine { private class WaitingForNextProbeState extends State { @Override public void enter() { + scheduleNextProbe(); + } + + private void scheduleNextProbe() { final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0); sendMessageDelayed(msg, mReevaluateDelayMs); mReevaluateDelayMs *= 2; diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java index c370959dd2cf..3ea9810f2d76 100644 --- a/services/core/java/com/android/server/connectivity/PacManager.java +++ b/services/core/java/com/android/server/connectivity/PacManager.java @@ -43,8 +43,6 @@ import com.android.net.IProxyCallback; import com.android.net.IProxyPortListener; import com.android.net.IProxyService; -import libcore.io.Streams; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; @@ -71,6 +69,11 @@ public class PacManager { private static final int DELAY_LONG = 4; private static final long MAX_PAC_SIZE = 20 * 1000 * 1000; + // Return values for #setCurrentProxyScriptUrl + enum ToSendOrNotToSendBroadcast { + DONT_SEND_BROADCAST, DO_SEND_BROADCAST + } + private String mCurrentPac; @GuardedBy("mProxyLock") private volatile Uri mPacUrl = Uri.EMPTY; @@ -171,13 +174,13 @@ public class PacManager { * PacManager will trigger a new broadcast when it is ready. * * @param proxy Proxy information that is about to be broadcast. - * @return Returns true when the broadcast should not be sent + * @return Returns whether the broadcast should be sent : either DO_ or DONT_SEND_BROADCAST */ - synchronized boolean setCurrentProxyScriptUrl(ProxyInfo proxy) { + synchronized ToSendOrNotToSendBroadcast setCurrentProxyScriptUrl(ProxyInfo proxy) { if (!Uri.EMPTY.equals(proxy.getPacFileUrl())) { if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) { // Allow to send broadcast, nothing to do. - return false; + return ToSendOrNotToSendBroadcast.DO_SEND_BROADCAST; } mPacUrl = proxy.getPacFileUrl(); mCurrentDelay = DELAY_1; @@ -185,7 +188,7 @@ public class PacManager { mHasDownloaded = false; getAlarmManager().cancel(mPacRefreshIntent); bind(); - return true; + return ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST; } else { getAlarmManager().cancel(mPacRefreshIntent); synchronized (mProxyLock) { @@ -201,7 +204,7 @@ public class PacManager { } } } - return false; + return ToSendOrNotToSendBroadcast.DO_SEND_BROADCAST; } } @@ -296,7 +299,7 @@ public class PacManager { Intent intent = new Intent(); intent.setClassName(PAC_PACKAGE, PAC_SERVICE); if ((mProxyConnection != null) && (mConnection != null)) { - // Already bound no need to bind again, just download the new file. + // Already bound: no need to bind again, just download the new file. mNetThreadHandler.post(mPacDownloader); return; } diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java index 15468ff05c08..fdddccd20714 100644 --- a/services/core/java/com/android/server/connectivity/ProxyTracker.java +++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java @@ -208,7 +208,10 @@ public class ProxyTracker { public void sendProxyBroadcast() { final ProxyInfo defaultProxy = getDefaultProxy(); final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, ""); - if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)) return; + if (mPacManager.setCurrentProxyScriptUrl(proxyInfo) + == PacManager.ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST) { + return; + } if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo); Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | diff --git a/services/core/java/com/android/server/deviceidle/BluetoothConstraint.java b/services/core/java/com/android/server/deviceidle/BluetoothConstraint.java new file mode 100644 index 000000000000..cc319bf23ddd --- /dev/null +++ b/services/core/java/com/android/server/deviceidle/BluetoothConstraint.java @@ -0,0 +1,135 @@ +/* + * 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.server.deviceidle; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.Message; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; +import com.android.server.DeviceIdleController; + +/** + * Track whether there are any active Bluetooth devices connected. + */ +public class BluetoothConstraint implements IDeviceIdleConstraint { + private static final String TAG = BluetoothConstraint.class.getSimpleName(); + private static final long INACTIVITY_TIMEOUT_MS = 20 * 60 * 1000L; + + private final Context mContext; + private final Handler mHandler; + private final DeviceIdleController.LocalService mLocalService; + private final BluetoothManager mBluetoothManager; + + private volatile boolean mConnected = true; + private volatile boolean mMonitoring = false; + + public BluetoothConstraint( + Context context, Handler handler, DeviceIdleController.LocalService localService) { + mContext = context; + mHandler = handler; + mLocalService = localService; + mBluetoothManager = mContext.getSystemService(BluetoothManager.class); + } + + @Override + public synchronized void startMonitoring() { + // Start by assuming we have a connected bluetooth device. + mConnected = true; + mMonitoring = true; + + // Register a receiver to get updates on bluetooth devices disconnecting or the + // adapter state changing. + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); + filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); + filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); + mContext.registerReceiver(mReceiver, filter); + + // Some devices will try to stay connected indefinitely. Set a timeout to ignore them. + mHandler.sendMessageDelayed( + Message.obtain(mHandler, mTimeoutCallback), INACTIVITY_TIMEOUT_MS); + + // Now we have the receiver registered, make a direct check for connected devices. + updateAndReportActiveLocked(); + } + + @Override + public synchronized void stopMonitoring() { + mContext.unregisterReceiver(mReceiver); + mHandler.removeCallbacks(mTimeoutCallback); + mMonitoring = false; + } + + private synchronized void cancelMonitoringDueToTimeout() { + if (mMonitoring) { + mMonitoring = false; + mLocalService.onConstraintStateChanged(this, /* active= */ false); + } + } + + /** + * Check the latest data from BluetoothManager and let DeviceIdleController know whether we + * have connected devices (for example TV remotes / gamepads) and thus want to stay awake. + */ + @GuardedBy("this") + private void updateAndReportActiveLocked() { + final boolean connected = isBluetoothConnected(mBluetoothManager); + if (connected != mConnected) { + mConnected = connected; + // If we lost all of our connections, we are on track to going into idle state. + mLocalService.onConstraintStateChanged(this, /* active= */ mConnected); + } + } + + /** + * True if the bluetooth adapter exists, is enabled, and has at least one GATT device connected. + */ + @VisibleForTesting + static boolean isBluetoothConnected(BluetoothManager bluetoothManager) { + BluetoothAdapter adapter = bluetoothManager.getAdapter(); + if (adapter != null && adapter.isEnabled()) { + return bluetoothManager.getConnectedDevices(BluetoothProfile.GATT).size() > 0; + } + return false; + } + + /** + * Registered in {@link #startMonitoring()}, unregistered in {@link #stopMonitoring()}. + */ + @VisibleForTesting + final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(intent.getAction())) { + mLocalService.exitIdle("bluetooth"); + } else { + updateAndReportActiveLocked(); + } + } + }; + + private final Runnable mTimeoutCallback = () -> cancelMonitoringDueToTimeout(); +} diff --git a/services/core/java/com/android/server/deviceidle/ConstraintController.java b/services/core/java/com/android/server/deviceidle/ConstraintController.java new file mode 100644 index 000000000000..6d52f7188d99 --- /dev/null +++ b/services/core/java/com/android/server/deviceidle/ConstraintController.java @@ -0,0 +1,32 @@ +/* + * 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.server.deviceidle; + +/** + * Device idle constraints for a specific form factor or use-case. + */ +public interface ConstraintController { + /** + * Begin any general continuing work and register all constraints. + */ + void start(); + + /** + * Unregister all constraints and stop any general work. + */ + void stop(); +} diff --git a/services/core/java/com/android/server/deviceidle/DeviceIdleConstraintTracker.java b/services/core/java/com/android/server/deviceidle/DeviceIdleConstraintTracker.java new file mode 100644 index 000000000000..4d5760ef9c86 --- /dev/null +++ b/services/core/java/com/android/server/deviceidle/DeviceIdleConstraintTracker.java @@ -0,0 +1,57 @@ +/* + * 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.server.deviceidle; + +/** + * Current state of an {@link IDeviceIdleConstraint}. + * + * If the current doze state is between leastActive and mostActive, then startMonitoring() will + * be the most recent call. Otherwise, stopMonitoring() is the most recent call. + */ +public class DeviceIdleConstraintTracker { + + /** + * Appears in "dumpsys deviceidle". + */ + public final String name; + + /** + * Whenever a constraint is active, it will keep the device at or above + * minState (provided the rule is currently in effect). + * + */ + public final int minState; + + /** + * Whether this constraint currently prevents going below {@link #minState}. + * + * When the state is set to exactly minState, active is automatically + * overwritten with {@code true}. + */ + public boolean active = false; + + /** + * Internal tracking for whether the {@link IDeviceIdleConstraint} on the other + * side has been told it needs to send updates. + */ + public boolean monitoring = false; + + public DeviceIdleConstraintTracker(final String name, int minState) { + this.name = name; + this.minState = minState; + } +} diff --git a/services/core/java/com/android/server/deviceidle/IDeviceIdleConstraint.java b/services/core/java/com/android/server/deviceidle/IDeviceIdleConstraint.java new file mode 100644 index 000000000000..f1f957307716 --- /dev/null +++ b/services/core/java/com/android/server/deviceidle/IDeviceIdleConstraint.java @@ -0,0 +1,67 @@ +/* + * 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.server.deviceidle; + +import android.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Implemented by OEM and/or Form Factor. System ones are built into the + * image regardless of build flavour but may still be switched off at run time. + * Individual feature flags at build time control which are used. We may + * also explore a local override for quick testing. + */ +public interface IDeviceIdleConstraint { + + /** + * A state for this constraint to block descent from. + * + * <p>These states are a subset of the states in DeviceIdleController that make sense for + * constraints to be able to block on. For example, {@link #SENSING_OR_ABOVE} clearly has + * defined "above" and "below" states. However, a hypothetical {@code QUICK_DOZE_OR_ABOVE} + * state would not have clear semantics as to what transitions should be blocked and which + * should be allowed. + */ + @IntDef(flag = false, value = { + ACTIVE, + SENSING_OR_ABOVE, + }) + @Retention(RetentionPolicy.SOURCE) + @interface MinimumState {} + + int ACTIVE = 0; + int SENSING_OR_ABOVE = 1; + + /** + * Begin tracking events for this constraint. + * + * <p>The device idle controller has reached a point where it is waiting for the all-clear + * from this tracker (possibly among others) in order to continue with progression into + * idle state. It will not proceed until one of the following happens: + * <ul> + * <li>The constraint reports inactive with {@code .setActive(false)}.</li> + * <li>The constraint is unregistered with {@code .unregisterDeviceIdleConstraint(this)}.</li> + * <li>A transition timeout in DeviceIdleController fires. + * </ul> + */ + void startMonitoring(); + + /** Stop checking for new events and do not call into LocalService with updates any more. */ + void stopMonitoring(); +} diff --git a/services/core/java/com/android/server/deviceidle/TvConstraintController.java b/services/core/java/com/android/server/deviceidle/TvConstraintController.java new file mode 100644 index 000000000000..2d472de6f5e1 --- /dev/null +++ b/services/core/java/com/android/server/deviceidle/TvConstraintController.java @@ -0,0 +1,66 @@ +/* + * 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.server.deviceidle; + +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Handler; + +import com.android.server.DeviceIdleController; +import com.android.server.LocalServices; + +/** + * Device idle constraints for television devices. + * + * <p>Televisions are devices with {@code FEATURE_LEANBACK_ONLY}. Other devices might support + * some kind of leanback mode but they should not follow the same rules for idle state. + */ +public class TvConstraintController implements ConstraintController { + private final Context mContext; + private final Handler mHandler; + private final DeviceIdleController.LocalService mDeviceIdleService; + + @Nullable + private final BluetoothConstraint mBluetoothConstraint; + + public TvConstraintController(Context context, Handler handler) { + mContext = context; + mHandler = handler; + mDeviceIdleService = LocalServices.getService(DeviceIdleController.LocalService.class); + + final PackageManager pm = context.getPackageManager(); + mBluetoothConstraint = pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH) + ? new BluetoothConstraint(mContext, mHandler, mDeviceIdleService) + : null; + } + + @Override + public void start() { + if (mBluetoothConstraint != null) { + mDeviceIdleService.registerDeviceIdleConstraint( + mBluetoothConstraint, "bluetooth", IDeviceIdleConstraint.SENSING_OR_ABOVE); + } + } + + @Override + public void stop() { + if (mBluetoothConstraint != null) { + mDeviceIdleService.unregisterDeviceIdleConstraint(mBluetoothConstraint); + } + } +} diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java index b6c82d3a66e4..73d3d9591529 100644 --- a/services/core/java/com/android/server/display/ColorDisplayService.java +++ b/services/core/java/com/android/server/display/ColorDisplayService.java @@ -16,6 +16,7 @@ package com.android.server.display; +import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; import android.animation.Animator; @@ -31,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; +import android.hardware.display.ColorDisplayManager; import android.hardware.display.IColorDisplayManager; import android.net.Uri; import android.opengl.Matrix; @@ -86,11 +88,80 @@ public final class ColorDisplayService extends SystemService { */ private static final ColorMatrixEvaluator COLOR_MATRIX_EVALUATOR = new ColorMatrixEvaluator(); - private final Handler mHandler; + private final TintController mNightDisplayTintController = new TintController() { + + private float[] mMatrixNightDisplay = new float[16]; + private final float[] mColorTempCoefficients = new float[9]; + + /** + * Set coefficients based on whether the color matrix is linear or not. + */ + @Override + public void setUp(Context context, boolean needsLinear) { + final String[] coefficients = context.getResources().getStringArray(needsLinear + ? R.array.config_nightDisplayColorTemperatureCoefficients + : R.array.config_nightDisplayColorTemperatureCoefficientsNative); + for (int i = 0; i < 9 && i < coefficients.length; i++) { + mColorTempCoefficients[i] = Float.parseFloat(coefficients[i]); + } + } + + @Override + public void setMatrix(int cct) { + if (mMatrixNightDisplay.length != 16) { + Slog.d(TAG, "The display transformation matrix must be 4x4"); + return; + } + + Matrix.setIdentityM(mMatrixNightDisplay, 0); + + final float squareTemperature = cct * cct; + final float red = squareTemperature * mColorTempCoefficients[0] + + cct * mColorTempCoefficients[1] + mColorTempCoefficients[2]; + final float green = squareTemperature * mColorTempCoefficients[3] + + cct * mColorTempCoefficients[4] + mColorTempCoefficients[5]; + final float blue = squareTemperature * mColorTempCoefficients[6] + + cct * mColorTempCoefficients[7] + mColorTempCoefficients[8]; + mMatrixNightDisplay[0] = red; + mMatrixNightDisplay[5] = green; + mMatrixNightDisplay[10] = blue; + } + + @Override + public float[] getMatrix() { + return isActivated() ? mMatrixNightDisplay : MATRIX_IDENTITY; + } + + @Override + public int getLevel() { + return LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; + } + }; + + private final TintController mDisplayWhiteBalanceTintController = new TintController() { + + private float[] mMatrixDisplayWhiteBalance = new float[16]; + + @Override + public void setUp(Context context, boolean needsLinear) { + } + + @Override + public float[] getMatrix() { + return isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY; + } + + @Override + public void setMatrix(int cct) { + } - private float[] mMatrixNight = new float[16]; + @Override + public int getLevel() { + return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; + } + }; - private final float[] mColorTempCoefficients = new float[9]; + private final Handler mHandler; private int mCurrentUser = UserHandle.USER_NULL; private ContentObserver mUserSetupObserver; @@ -98,11 +169,13 @@ public final class ColorDisplayService extends SystemService { private ColorDisplayController mNightDisplayController; private ContentObserver mContentObserver; - private ValueAnimator mColorMatrixAnimator; - private Boolean mIsNightDisplayActivated; + private DisplayWhiteBalanceListener mDisplayWhiteBalanceListener; + private NightDisplayAutoMode mNightDisplayAutoMode; + private Integer mDisplayWhiteBalanceColorTemperature; + public ColorDisplayService(Context context) { super(context); mHandler = new Handler(Looper.getMainLooper()); @@ -111,6 +184,7 @@ public final class ColorDisplayService extends SystemService { @Override public void onStart() { publishBinderService(Context.COLOR_DISPLAY_SERVICE, new BinderService()); + publishLocalService(ColorDisplayServiceInternal.class, new ColorDisplayServiceInternal()); } @Override @@ -232,6 +306,9 @@ public final class ColorDisplayService extends SystemService { case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED: onAccessibilityTransformChanged(); break; + case Secure.DISPLAY_WHITE_BALANCE_ENABLED: + onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); + break; } } } @@ -256,25 +333,41 @@ public final class ColorDisplayService extends SystemService { cr.registerContentObserver( Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED), false /* notifyForDescendants */, mContentObserver, mCurrentUser); + cr.registerContentObserver(Secure.getUriFor(Secure.DISPLAY_WHITE_BALANCE_ENABLED), + false /* notifyForDescendants */, mContentObserver, mCurrentUser); // Set the color mode, if valid, and immediately apply the updated tint matrix based on the // existing activated state. This ensures consistency of tint across the color mode change. onDisplayColorModeChanged(mNightDisplayController.getColorMode()); - // Reset the activated state. - mIsNightDisplayActivated = null; + if (ColorDisplayManager.isNightDisplayAvailable(getContext())) { + // Reset the activated state. + mNightDisplayTintController.setActivated(null); + + // Prepare the night display color transformation matrix. + mNightDisplayTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix()); + mNightDisplayTintController.setMatrix(mNightDisplayController.getColorTemperature()); - setCoefficientMatrix(getContext(), DisplayTransformManager.needsLinearColorMatrix()); + // Initialize the current auto mode. + onNightDisplayAutoModeChanged(mNightDisplayController.getAutoMode()); - // Prepare color transformation matrix. - setMatrix(mNightDisplayController.getColorTemperature(), mMatrixNight); + // Force the initialization current activated state. + if (mNightDisplayTintController.isActivatedStateNotSet()) { + onNightDisplayActivated(mNightDisplayController.isActivated()); + } + } - // Initialize the current auto mode. - onNightDisplayAutoModeChanged(mNightDisplayController.getAutoMode()); + if (ColorDisplayManager.isDisplayWhiteBalanceAvailable(getContext())) { + // Prepare the display white balance transform matrix. + mDisplayWhiteBalanceTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix()); + if (mDisplayWhiteBalanceColorTemperature != null) { + mDisplayWhiteBalanceTintController + .setMatrix(mDisplayWhiteBalanceColorTemperature); + } - // Force the initialization current activated state. - if (mIsNightDisplayActivated == null) { - onNightDisplayActivated(mNightDisplayController.isActivated()); + onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); } } @@ -287,28 +380,31 @@ public final class ColorDisplayService extends SystemService { mNightDisplayController = null; } - if (mNightDisplayAutoMode != null) { - mNightDisplayAutoMode.onStop(); - mNightDisplayAutoMode = null; + if (ColorDisplayManager.isNightDisplayAvailable(getContext())) { + if (mNightDisplayAutoMode != null) { + mNightDisplayAutoMode.onStop(); + mNightDisplayAutoMode = null; + } + mNightDisplayTintController.endAnimator(); } - if (mColorMatrixAnimator != null) { - mColorMatrixAnimator.end(); - mColorMatrixAnimator = null; + if (ColorDisplayManager.isDisplayWhiteBalanceAvailable(getContext())) { + mDisplayWhiteBalanceTintController.endAnimator(); } } private void onNightDisplayActivated(boolean activated) { - if (mIsNightDisplayActivated == null || mIsNightDisplayActivated != activated) { + if (mNightDisplayTintController.isActivatedStateNotSet() + || mNightDisplayTintController.isActivated() != activated) { Slog.i(TAG, activated ? "Turning on night display" : "Turning off night display"); - mIsNightDisplayActivated = activated; + mNightDisplayTintController.setActivated(activated); if (mNightDisplayAutoMode != null) { mNightDisplayAutoMode.onActivated(activated); } - applyTint(false); + applyTint(mNightDisplayTintController, false); } } @@ -348,8 +444,8 @@ public final class ColorDisplayService extends SystemService { } private void onNightDisplayColorTemperatureChanged(int colorTemperature) { - setMatrix(colorTemperature, mMatrixNight); - applyTint(true); + mNightDisplayTintController.setMatrix(colorTemperature); + applyTint(mNightDisplayTintController, true); } private void onDisplayColorModeChanged(int mode) { @@ -357,66 +453,53 @@ public final class ColorDisplayService extends SystemService { return; } - // Cancel the night display tint animator if it's running. - if (mColorMatrixAnimator != null) { - mColorMatrixAnimator.cancel(); - } + mNightDisplayTintController.cancelAnimator(); + mDisplayWhiteBalanceTintController.cancelAnimator(); + + mNightDisplayTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); + mNightDisplayTintController.setMatrix(mNightDisplayController.getColorTemperature()); - setCoefficientMatrix(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); - setMatrix(mNightDisplayController.getColorTemperature(), mMatrixNight); + mDisplayWhiteBalanceTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); + if (mDisplayWhiteBalanceColorTemperature != null) { + mDisplayWhiteBalanceTintController.setMatrix(mDisplayWhiteBalanceColorTemperature); + } final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); - dtm.setColorMode(mode, (mIsNightDisplayActivated != null && mIsNightDisplayActivated) - ? mMatrixNight : MATRIX_IDENTITY); + dtm.setColorMode(mode, mNightDisplayTintController.getMatrix()); } private void onAccessibilityTransformChanged() { onDisplayColorModeChanged(mNightDisplayController.getColorMode()); } - /** - * Set coefficients based on whether the color matrix is linear or not. - */ - private void setCoefficientMatrix(Context context, boolean needsLinear) { - final String[] coefficients = context.getResources().getStringArray(needsLinear - ? R.array.config_nightDisplayColorTemperatureCoefficients - : R.array.config_nightDisplayColorTemperatureCoefficientsNative); - for (int i = 0; i < 9 && i < coefficients.length; i++) { - mColorTempCoefficients[i] = Float.parseFloat(coefficients[i]); - } - } /** * Applies current color temperature matrix, or removes it if deactivated. * * @param immediate {@code true} skips transition animation */ - private void applyTint(boolean immediate) { - // Cancel the old animator if still running. - if (mColorMatrixAnimator != null) { - mColorMatrixAnimator.cancel(); - } + private void applyTint(TintController tintController, boolean immediate) { + tintController.cancelAnimator(); final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); - final float[] from = dtm.getColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY); - final float[] to = mIsNightDisplayActivated ? mMatrixNight : MATRIX_IDENTITY; + final float[] from = dtm.getColorMatrix(tintController.getLevel()); + final float[] to = tintController.getMatrix(); if (immediate) { - dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, to); + dtm.setColorMatrix(tintController.getLevel(), to); } else { - mColorMatrixAnimator = ValueAnimator.ofObject(COLOR_MATRIX_EVALUATOR, - from == null ? MATRIX_IDENTITY : from, to); - mColorMatrixAnimator.setDuration(TRANSITION_DURATION); - mColorMatrixAnimator.setInterpolator(AnimationUtils.loadInterpolator( + tintController.setAnimator(ValueAnimator.ofObject(COLOR_MATRIX_EVALUATOR, + from == null ? MATRIX_IDENTITY : from, to)); + tintController.getAnimator().setDuration(TRANSITION_DURATION); + tintController.getAnimator().setInterpolator(AnimationUtils.loadInterpolator( getContext(), android.R.interpolator.fast_out_slow_in)); - mColorMatrixAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animator) { - final float[] value = (float[]) animator.getAnimatedValue(); - dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, value); - } + tintController.getAnimator().addUpdateListener((ValueAnimator animator) -> { + final float[] value = (float[]) animator.getAnimatedValue(); + dtm.setColorMatrix(tintController.getLevel(), value); }); - mColorMatrixAnimator.addListener(new AnimatorListenerAdapter() { + tintController.getAnimator().addListener(new AnimatorListenerAdapter() { private boolean mIsCancelled; @@ -431,42 +514,16 @@ public final class ColorDisplayService extends SystemService { // Ensure final color matrix is set at the end of the animation. If the // animation is cancelled then don't set the final color matrix so the new // animator can pick up from where this one left off. - dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, to); + dtm.setColorMatrix(tintController.getLevel(), to); } - mColorMatrixAnimator = null; + tintController.setAnimator(null); } }); - mColorMatrixAnimator.start(); + tintController.getAnimator().start(); } } /** - * Set the color transformation {@code MATRIX_NIGHT} to the given color temperature. - * - * @param colorTemperature color temperature in Kelvin - * @param outTemp the 4x4 display transformation matrix for that color temperature - */ - private void setMatrix(int colorTemperature, float[] outTemp) { - if (outTemp.length != 16) { - Slog.d(TAG, "The display transformation matrix must be 4x4"); - return; - } - - Matrix.setIdentityM(mMatrixNight, 0); - - final float squareTemperature = colorTemperature * colorTemperature; - final float red = squareTemperature * mColorTempCoefficients[0] - + colorTemperature * mColorTempCoefficients[1] + mColorTempCoefficients[2]; - final float green = squareTemperature * mColorTempCoefficients[3] - + colorTemperature * mColorTempCoefficients[4] + mColorTempCoefficients[5]; - final float blue = squareTemperature * mColorTempCoefficients[6] - + colorTemperature * mColorTempCoefficients[7] + mColorTempCoefficients[8]; - outTemp[0] = red; - outTemp[5] = green; - outTemp[10] = blue; - } - - /** * Returns the first date time corresponding to the local time that occurs before the provided * date time. * @@ -498,6 +555,18 @@ public final class ColorDisplayService extends SystemService { return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt; } + private void onDisplayWhiteBalanceEnabled(boolean enabled) { + mDisplayWhiteBalanceTintController.setActivated(enabled); + if (mDisplayWhiteBalanceListener != null) { + mDisplayWhiteBalanceListener.onDisplayWhiteBalanceStatusChanged(enabled); + } + } + + private boolean isDisplayWhiteBalanceSettingEnabled() { + return Secure.getIntForUser(getContext().getContentResolver(), + Secure.DISPLAY_WHITE_BALANCE_ENABLED, 0, mCurrentUser) == 1; + } + private boolean isDeviceColorManagedInternal() { final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); return dtm.isDeviceColorManaged(); @@ -507,7 +576,7 @@ public final class ColorDisplayService extends SystemService { * Returns the last time the night display transform activation state was changed, or {@link * LocalDateTime#MIN} if night display has never been activated. */ - private @NonNull LocalDateTime getNightDisplayLastActivatedTimeSetting() { + private LocalDateTime getNightDisplayLastActivatedTimeSetting() { final ContentResolver cr = getContext().getContentResolver(); final String lastActivatedTime = Secure.getStringForUser( cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, getContext().getUserId()); @@ -577,11 +646,12 @@ public final class ColorDisplayService extends SystemService { } } - if (mIsNightDisplayActivated == null || mIsNightDisplayActivated != activate) { + if (mNightDisplayTintController.isActivatedStateNotSet() || ( + mNightDisplayTintController.isActivated() != activate)) { mNightDisplayController.setActivated(activate); } - updateNextAlarm(mIsNightDisplayActivated, now); + updateNextAlarm(mNightDisplayTintController.isActivated(), now); } private void updateNextAlarm(@Nullable Boolean activated, @NonNull LocalDateTime now) { @@ -672,7 +742,8 @@ public final class ColorDisplayService extends SystemService { } } - if (mIsNightDisplayActivated == null || mIsNightDisplayActivated != activate) { + if (mNightDisplayTintController.isActivatedStateNotSet() || ( + mNightDisplayTintController.isActivated() != activate)) { mNightDisplayController.setActivated(activate); } } @@ -724,6 +795,115 @@ 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; + } + + /** + * 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(); + } + + /** + * Local service that allows color transforms to be enabled from other system services. + */ + public final class ColorDisplayServiceInternal { + + /** + * Set the current CCT value for the display white balance transform, and if the transform + * is enabled, apply it. + * + * @param cct the color temperature in Kelvin. + */ + public boolean setDisplayWhiteBalanceColorTemperature(int cct) { + // Update the transform matrix even if it can't be applied. + mDisplayWhiteBalanceColorTemperature = cct; + mDisplayWhiteBalanceTintController.setMatrix(cct); + + if (mDisplayWhiteBalanceTintController.isActivated()) { + applyTint(mDisplayWhiteBalanceTintController, true); + return true; + } + return false; + } + + /** + * Sets the listener and returns whether display white balance is currently enabled. + */ + public boolean setDisplayWhiteBalanceListener(DisplayWhiteBalanceListener listener) { + mDisplayWhiteBalanceListener = listener; + return mDisplayWhiteBalanceTintController.isActivated(); + } + } + + /** + * Listener for changes in display white balance status. + */ + public interface DisplayWhiteBalanceListener { + + /** + * Notify that the display white balance status has changed, either due to preemption by + * another transform or the feature being turned off. + */ + void onDisplayWhiteBalanceStatusChanged(boolean enabled); + } + private final class BinderService extends IColorDisplayManager.Stub { @Override diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java index 4ad26dae8380..a5e9728e4b68 100644 --- a/services/core/java/com/android/server/display/DisplayTransformManager.java +++ b/services/core/java/com/android/server/display/DisplayTransformManager.java @@ -45,6 +45,10 @@ public class DisplayTransformManager { */ public static final int LEVEL_COLOR_MATRIX_NIGHT_DISPLAY = 100; /** + * Color transform level used by display white balance to adjust the display's white point. + */ + public static final int LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE = 125; + /** * Color transform level used to adjust the color saturation of the display. */ public static final int LEVEL_COLOR_MATRIX_SATURATION = 150; diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index c0c4a6e8310e..a3ebe2408fa3 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -38,6 +38,7 @@ import android.util.SparseBooleanArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; +import com.android.internal.infra.AbstractRemoteService; import com.android.internal.os.BackgroundThread; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; @@ -86,13 +87,22 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem protected final Object mLock = new Object(); /** + * Object used to define the name of the service component used to create + * {@link com.android.internal.infra.AbstractRemoteService} instances. + */ + @Nullable + protected final ServiceNameResolver mServiceNameResolver; + + /** * Whether the service should log debug statements. */ + //TODO(b/117779333): consider using constants for these guards public boolean verbose = false; /** * Whether the service should log verbose statements. */ + //TODO(b/117779333): consider using constants for these guards public boolean debug = false; /** @@ -119,13 +129,24 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem * Default constructor. * * @param context system context. + * @param serviceNameResolver resolver for + * {@link com.android.internal.infra.AbstractRemoteService} instances, or + * {@code null} when the service doesn't bind to remote services. * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that * disables the service. */ protected AbstractMasterSystemService(@NonNull Context context, + @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty) { super(context); + mServiceNameResolver = serviceNameResolver; + if (mServiceNameResolver != null) { + mServiceNameResolver + .setOnTemporaryServiceNameChangedCallback( + (u, s) -> updateCachedServiceLocked(u)); + + } if (disallowProperty == null) { mDisabledUsers = null; } else { @@ -199,6 +220,20 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } /** + * Checks whether the service is allowed to bind to an instant-app. + * + * <p>Typically called by subclasses when creating {@link AbstractRemoteService} instances. + * + * <p><b>NOTE: </b>must not be called by {@code ShellCommand} as it does not check for + * permission. + */ + public final boolean isBindInstantServiceAllowed() { + synchronized (mLock) { + return mAllowInstantService; + } + } + + /** * Sets whether the service is allowed to bind to an instant-app. * * <p>Typically called by {@code ShellCommand} during CTS tests. @@ -294,6 +329,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem * * @return a new instance. */ + @Nullable protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled); /** @@ -421,11 +457,11 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem /** * Removes a cached service for a given user. * - * @return the removed service; + * @return the removed service. */ @GuardedBy("mLock") @NonNull - private S removeCachedServiceLocked(@UserIdInt int userId) { + protected final S removeCachedServiceLocked(@UserIdInt int userId) { final S service = peekServiceForUserLocked(userId); if (service != null) { mServicesCache.delete(userId); @@ -471,6 +507,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); + if (mServiceNameResolver != null) { + pw.print(prefix); pw.print("Name resolver: "); + mServiceNameResolver.dumpShort(pw); pw.println(); + } pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers); pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService); final String settingsProperty = getServiceSettingsProperty(); diff --git a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java index 28a809401d71..556e4892807c 100644 --- a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java @@ -55,8 +55,6 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst protected final M mMaster; - private final ServiceNameResolver mServiceNameResolver; - /** * Whether service was disabled for user due to {@link UserManager} restrictions. */ @@ -72,13 +70,9 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst @GuardedBy("mLock") private ServiceInfo mServiceInfo; - protected AbstractPerUserSystemService(@NonNull M master, - @NonNull ServiceNameResolver serviceNamer, @NonNull Object lock, + protected AbstractPerUserSystemService(@NonNull M master, @NonNull Object lock, @UserIdInt int userId) { mMaster = master; - mServiceNameResolver = serviceNamer; - mServiceNameResolver - .setOnTemporaryServiceNameChangedCallback(() -> updateLocked(mDisabled)); mLock = lock; mUserId = userId; } @@ -86,11 +80,21 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst /** * Creates a new {@link ServiceInfo} for the given service name. * + * <p><b>MUST</b> be overridden by subclasses that bind to an + * {@link com.android.internal.infra.AbstractRemoteService}. + * * @throws NameNotFoundException if the service does not exist. * @throws SecurityException if the service does not have the proper permissions to be bound to. + * @throws UnsupportedOperationException if subclass binds to a remote service but does not + * overrides it. + * + * @return new {@link ServiceInfo}, */ - protected abstract ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent) - throws NameNotFoundException; + protected @NonNull ServiceInfo newServiceInfoLocked( + @SuppressWarnings("unused") @NonNull ComponentName serviceComponent) + throws NameNotFoundException { + throw new UnsupportedOperationException("not overridden"); + } /** * Callback called when an app has been updated. @@ -134,39 +138,51 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst mSetupComplete = isSetupCompletedLocked(); mDisabled = disabled; + + updateServiceInfoLocked(); + return wasEnabled != isEnabledLocked(); + } + + /** + * Updates the internal reference to the service info, and returns the service's component. + */ + protected final ComponentName updateServiceInfoLocked() { ComponentName serviceComponent = null; - ServiceInfo serviceInfo = null; - final String componentName = getComponentNameLocked(); - if (!TextUtils.isEmpty(componentName)) { - try { - serviceComponent = ComponentName.unflattenFromString(componentName); - serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, - 0, mUserId); - if (serviceInfo == null) { - Slog.e(mTag, "Bad service name: " + componentName); + if (mMaster.mServiceNameResolver != null) { + ServiceInfo serviceInfo = null; + final String componentName = getComponentNameLocked(); + if (!TextUtils.isEmpty(componentName)) { + try { + serviceComponent = ComponentName.unflattenFromString(componentName); + serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, + 0, mUserId); + if (serviceInfo == null) { + Slog.e(mTag, "Bad service name: " + componentName); + } + } catch (RuntimeException | RemoteException e) { + Slog.e(mTag, "Error getting service info for '" + componentName + "': " + e); + serviceInfo = null; } - } catch (RuntimeException | RemoteException e) { - Slog.e(mTag, "Error getting service info for '" + componentName + "': " + e); - serviceInfo = null; } - } - try { - if (serviceInfo != null) { - mServiceInfo = newServiceInfo(serviceComponent); - if (mMaster.debug) { - Slog.d(mTag, "Set component for user " + mUserId + " as " + mServiceInfo); + try { + if (serviceInfo != null) { + mServiceInfo = newServiceInfoLocked(serviceComponent); + if (mMaster.debug) { + Slog.d(mTag, "Set component for user " + mUserId + " as " + + serviceComponent + " and info as " + mServiceInfo); + } + } else { + mServiceInfo = null; + if (mMaster.debug) { + Slog.d(mTag, "Reset component for user " + mUserId + ":" + componentName); + } } - } else { + } catch (Exception e) { + Slog.e(mTag, "Bad ServiceInfo for '" + componentName + "': " + e); mServiceInfo = null; - if (mMaster.debug) { - Slog.d(mTag, "Reset component for user " + mUserId + ":" + componentName); - } } - } catch (Exception e) { - Slog.e(mTag, "Bad ServiceInfo for '" + componentName + "': " + e); - mServiceInfo = null; } - return wasEnabled != isEnabledLocked(); + return serviceComponent; } /** @@ -200,15 +216,15 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst * Gets the current name of the service, which is either the default service or the * {@link #setTemporaryServiceLocked(String, int) temporary one}. */ - protected final String getComponentNameLocked() { - return mServiceNameResolver.getServiceNameLocked(); + protected final @Nullable String getComponentNameLocked() { + return mMaster.mServiceNameResolver.getServiceName(mUserId); } /** * Checks whether the current service for the user was temporarily set. */ public final boolean isTemporaryServiceSetLocked() { - return mServiceNameResolver.isTemporaryLocked(); + return mMaster.mServiceNameResolver.isTemporary(mUserId); } /** @@ -219,14 +235,14 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst * to the default component after this timeout expires). */ protected final void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) { - mServiceNameResolver.setTemporaryServiceLocked(componentName, durationMs); + mMaster.mServiceNameResolver.setTemporaryService(mUserId, componentName, durationMs); } /** * Resets the temporary service implementation to the default component. */ protected final void resetTemporaryServiceLocked() { - mServiceNameResolver.resetTemporaryServiceLocked(); + mMaster.mServiceNameResolver.resetTemporaryService(mUserId); } /** @@ -272,8 +288,16 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst } /** + * Removes the service from the master's cache. + */ + protected final void removeSelfFromCacheLocked() { + mMaster.removeCachedServiceLocked(mUserId); + } + + /** * Whether the service should log debug statements. */ + //TODO(b/117779333): consider using constants for these guards public final boolean isDebug() { return mMaster.debug; } @@ -281,6 +305,7 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst /** * Whether the service should log verbose statements. */ + //TODO(b/117779333): consider using constants for these guards public final boolean isVerbose() { return mMaster.verbose; } @@ -313,13 +338,16 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst @GuardedBy("mLock") protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) { pw.print(prefix); pw.print("User: "); pw.println(mUserId); + if (mMaster.mServiceNameResolver != null) { + pw.print(prefix); pw.print("Name resolver: "); + mMaster.mServiceNameResolver.dumpShort(pw, mUserId); pw.println(); + } pw.print(prefix); pw.print("Disabled by UserManager: "); pw.println(mDisabled); pw.print(prefix); pw.print("Setup complete: "); pw.println(mSetupComplete); if (mServiceInfo != null) { pw.print(prefix); pw.print("Service UID: "); pw.println(mServiceInfo.applicationInfo.uid); } - pw.print(prefix); pw.print("Name resolver: "); mServiceNameResolver.dumpShortLocked(pw); pw.println(); } } diff --git a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java index 27822d543f2a..7027246a1bbe 100644 --- a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java +++ b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java @@ -26,6 +26,7 @@ import android.os.Message; import android.os.SystemClock; import android.text.TextUtils; import android.util.Slog; +import android.util.SparseArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; @@ -42,23 +43,22 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR private static final String TAG = FrameworkResourcesServiceNameResolver.class.getSimpleName(); - /** Handler message to {@link #resetTemporaryServiceLocked()} */ + /** Handler message to {@link #resetTemporaryService(int)} */ private static final int MSG_RESET_TEMPORARY_SERVICE = 0; private final @NonNull Context mContext; - private final @NonNull @UserIdInt int mUserId; - private final @NonNull Object mLock; + private final @NonNull Object mLock = new Object(); private final @StringRes int mResourceId; - private @Nullable Runnable mOnSetCallback; + private @Nullable NameResolverListener mOnSetCallback; /** - * Temporary service name set by {@link #setTemporaryServiceLocked(String, int)}. + * Map of temporary service name set by {@link #setTemporaryService(int, String, int)}, + * keyed by {@code userId}. * * <p>Typically used by Shell command and/or CTS tests. */ @GuardedBy("mLock") - @Nullable - private String mTemporaryServiceName; + private final SparseArray<String> mTemporaryServiceNames = new SparseArray<>(); /** * When the temporary service will expire (and reset back to the default). @@ -72,99 +72,123 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR @GuardedBy("mLock") private Handler mTemporaryHandler; - public FrameworkResourcesServiceNameResolver(@NonNull Context context, @UserIdInt int userId, - @NonNull Object lock, @StringRes int resourceId) { - mLock = lock; + public FrameworkResourcesServiceNameResolver(@NonNull Context context, + @StringRes int resourceId) { mContext = context; - mUserId = userId; mResourceId = resourceId; } @Override - public void setOnTemporaryServiceNameChangedCallback(@NonNull Runnable callback) { - this.mOnSetCallback = callback; + public void setOnTemporaryServiceNameChangedCallback(@NonNull NameResolverListener callback) { + synchronized (mLock) { + this.mOnSetCallback = callback; + } } @Override - public String getDefaultServiceName() { - final String name = mContext.getString(mResourceId); - return TextUtils.isEmpty(name) ? null : name; + public String getDefaultServiceName(@UserIdInt int userId) { + synchronized (mLock) { + final String name = mContext.getString(mResourceId); + return TextUtils.isEmpty(name) ? null : name; + } } @Override - public String getServiceNameLocked() { - if (mTemporaryServiceName != null) { - // Always log it, as it should only be used on CTS or during development - Slog.w(TAG, "getComponentName(): using temporary name " + mTemporaryServiceName); - return mTemporaryServiceName; - } else { - return getDefaultServiceName(); + public String getServiceName(@UserIdInt int userId) { + synchronized (mLock) { + final String temporaryName = mTemporaryServiceNames.get(userId); + if (temporaryName != null) { + // Always log it, as it should only be used on CTS or during development + Slog.w(TAG, "getComponentName(): using temporary name " + temporaryName + + " for user " + userId); + return temporaryName; + } else { + return getDefaultServiceName(userId); + } } } @Override - public boolean isTemporaryLocked() { - return mTemporaryServiceName != null; + public boolean isTemporary(@UserIdInt int userId) { + synchronized (mLock) { + return mTemporaryServiceNames.get(userId) != null; + } } @Override - public void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) { - mTemporaryServiceName = componentName; - - if (mTemporaryHandler == null) { - mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) { - @Override - public void handleMessage(Message msg) { - if (msg.what == MSG_RESET_TEMPORARY_SERVICE) { - synchronized (mLock) { - resetTemporaryServiceLocked(); + public void setTemporaryService(@UserIdInt int userId, @NonNull String componentName, + int durationMs) { + synchronized (mLock) { + mTemporaryServiceNames.put(userId, componentName); + + if (mTemporaryHandler == null) { + mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) { + @Override + public void handleMessage(Message msg) { + if (msg.what == MSG_RESET_TEMPORARY_SERVICE) { + synchronized (mLock) { + resetTemporaryService(userId); + } + } else { + Slog.wtf(TAG, "invalid handler msg: " + msg); } - } else { - Slog.wtf(TAG, "invalid handler msg: " + msg); } - } - }; - } else { - removeResetTemporaryServiceMessageLocked(); + }; + } else { + mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); + } + mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs; + mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs); + notifyTemporaryServiceNameChangedLocked(userId, componentName); } - mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs; - mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs); - onServiceNameChanged(); } @Override - public void resetTemporaryServiceLocked() { - Slog.i(TAG, "resetting temporary service from " + mTemporaryServiceName); - mTemporaryServiceName = null; - if (mTemporaryHandler != null) { - removeResetTemporaryServiceMessageLocked(); - mTemporaryHandler = null; + public void resetTemporaryService(@UserIdInt int userId) { + synchronized (mLock) { + Slog.i(TAG, "resetting temporary service for user " + userId + " from " + + mTemporaryServiceNames.get(userId)); + mTemporaryServiceNames.remove(userId); + if (mTemporaryHandler != null) { + mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); + mTemporaryHandler = null; + } + notifyTemporaryServiceNameChangedLocked(userId, /* newTemporaryName= */ null); } - onServiceNameChanged(); + } + + @Override + public String toString() { + return "FrameworkResourcesServiceNamer: temps=" + mTemporaryServiceNames; } // TODO(b/117779333): support proto @Override - public void dumpShortLocked(@NonNull PrintWriter pw) { - pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId); - if (mTemporaryServiceName != null) { - pw.print(", tmpName="); pw.print(mTemporaryServiceName); - final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime(); - pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print(")"); - pw.print(", defaultName="); pw.println(getDefaultServiceName()); - } else { - pw.print(", serviceName="); pw.println(getDefaultServiceName()); + public void dumpShort(@NonNull PrintWriter pw) { + synchronized (mLock) { + pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId); + pw.print(", numberTemps="); pw.print(mTemporaryServiceNames.size()); } } - private void onServiceNameChanged() { - if (mOnSetCallback != null) { - mOnSetCallback.run(); + // TODO(b/117779333): support proto + @Override + public void dumpShort(@NonNull PrintWriter pw, @UserIdInt int userId) { + synchronized (mLock) { + final String temporaryName = mTemporaryServiceNames.get(userId); + if (temporaryName != null) { + pw.print("tmpName="); pw.print(temporaryName); + final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime(); + pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print("), "); + } + pw.print("defaultName="); pw.println(getDefaultServiceName(userId)); } } - private void removeResetTemporaryServiceMessageLocked() { - // NOTE: caller should already have checked it - mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); + private void notifyTemporaryServiceNameChangedLocked(@UserIdInt int userId, + @Nullable String newTemporaryName) { + if (mOnSetCallback != null) { + mOnSetCallback.onNameResolved(userId, newTemporaryName); + } } } diff --git a/services/core/java/com/android/server/infra/SecureSettingsServiceNameResolver.java b/services/core/java/com/android/server/infra/SecureSettingsServiceNameResolver.java index 7af8f6076160..bcaa9188ca62 100644 --- a/services/core/java/com/android/server/infra/SecureSettingsServiceNameResolver.java +++ b/services/core/java/com/android/server/infra/SecureSettingsServiceNameResolver.java @@ -31,27 +31,29 @@ import java.io.PrintWriter; public final class SecureSettingsServiceNameResolver implements ServiceNameResolver { private final @NonNull Context mContext; - private final @NonNull @UserIdInt int mUserId; @NonNull private final String mProperty; - public SecureSettingsServiceNameResolver(@NonNull Context context, @UserIdInt int userId, - @NonNull String property) { + public SecureSettingsServiceNameResolver(@NonNull Context context, @NonNull String property) { mContext = context; - mUserId = userId; mProperty = property; } @Override - public String getDefaultServiceName() { - return Settings.Secure.getStringForUser(mContext.getContentResolver(), mProperty, mUserId); + public String getDefaultServiceName(@UserIdInt int userId) { + return Settings.Secure.getStringForUser(mContext.getContentResolver(), mProperty, userId); } // TODO(b/117779333): support proto @Override - public void dumpShortLocked(@NonNull PrintWriter pw) { + public void dumpShort(@NonNull PrintWriter pw) { pw.print("SecureSettingsServiceNamer: prop="); pw.print(mProperty); - pw.print(", value="); pw.println(getDefaultServiceName()); + } + + // TODO(b/117779333): support proto + @Override + public void dumpShort(@NonNull PrintWriter pw, @UserIdInt int userId) { + pw.print("defaultService="); pw.print(getDefaultServiceName(userId)); } } diff --git a/services/core/java/com/android/server/infra/ServiceNameResolver.java b/services/core/java/com/android/server/infra/ServiceNameResolver.java index fd87e3d32b1d..bc11ff302ca9 100644 --- a/services/core/java/com/android/server/infra/ServiceNameResolver.java +++ b/services/core/java/com/android/server/infra/ServiceNameResolver.java @@ -17,6 +17,7 @@ package com.android.server.infra; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import com.android.internal.infra.AbstractRemoteService; @@ -31,78 +32,90 @@ import java.io.PrintWriter; public interface ServiceNameResolver { /** + * Listener for name changes. + */ + public interface NameResolverListener { + + /** + * The name change callback. + */ + void onNameResolved(@UserIdInt int userId, @Nullable String serviceName); + } + + /** * Sets a callback that is called after the service is - * {@link #setTemporaryServiceLocked(String, int) set} or - * {@link #resetTemporaryServiceLocked() reset}. + * {@link #setTemporaryService(int, String, int) set} or + * {@link #resetTemporaryService(int) reset}. * * <p>Typically called after the object is constructed. */ default void setOnTemporaryServiceNameChangedCallback( - @SuppressWarnings("unused") @NonNull Runnable callback) { + @SuppressWarnings("unused") @NonNull NameResolverListener callback) { // ignored by default } /** - * Gets the default name of the service. + * Gets the default name of the service for the given user. * * <p>Typically implemented by reading a Settings property or framework resource. */ @Nullable - String getDefaultServiceName(); + String getDefaultServiceName(@UserIdInt int userId); /** - * Gets the current name of the service. - * - * <p>Must be called after acquiring this object's lock. + * Gets the current name of the service for the given user * - * @return either the temporary name (set by {@link #setTemporaryServiceLocked(String, int)}, or - * the {@link #getDefaultServiceName() default name}. + * @return either the temporary name (set by + * {@link #setTemporaryService(int, String, int)}, or the + * {@link #getDefaultServiceName(int) default name}. */ @Nullable - default String getServiceNameLocked() { - return getDefaultServiceName(); + default String getServiceName(@UserIdInt int userId) { + return getDefaultServiceName(userId); } /** - * Checks whether the current service is temporary. - * - * <p>Must be called after acquiring this object's lock. + * Checks whether the current service is temporary for the given user. */ - default boolean isTemporaryLocked() { + default boolean isTemporary(@SuppressWarnings("unused") @UserIdInt int userId) { return false; } /** - * Temporarily sets the service implementation. - * - * <p>Must be called after acquiring this object's lock. + * Temporarily sets the service implementation for the given user. * + * @param userId user handle * @param componentName name of the new component * @param durationMs how long the change will be valid (the service will be automatically reset * to the default component after this timeout expires). * * @throws UnsupportedOperationException if not implemented. */ - default void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) { + default void setTemporaryService(@UserIdInt int userId, @NonNull String componentName, + int durationMs) { throw new UnsupportedOperationException("temporary user not supported"); } /** - * Resets the temporary service implementation to the default component. + * Resets the temporary service implementation to the default component for the given user. * - * <p>Must be called after acquiring this object's lock. + * @param userId user handle * * @throws UnsupportedOperationException if not implemented. */ - default void resetTemporaryServiceLocked() { + default void resetTemporaryService(@UserIdInt int userId) { throw new UnsupportedOperationException("temporary user not supported"); } /** - * Dump this object in just one line (without calling {@code println}. - * - * <p>Must be called after acquiring this object's lock. + * Dumps the generic info in just one line (without calling {@code println}. + */ + // TODO(b/117779333): support proto + void dumpShort(@NonNull PrintWriter pw); + + /** + * Dumps the user-specific info in just one line (without calling {@code println}. */ // TODO(b/117779333): support proto - void dumpShortLocked(@NonNull PrintWriter pw); + void dumpShort(@NonNull PrintWriter pw, @UserIdInt int userId); } diff --git a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java new file mode 100644 index 000000000000..f79ac164ef55 --- /dev/null +++ b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java @@ -0,0 +1,284 @@ +/* + * 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.server.inputmethod; + +import android.annotation.NonNull; +import android.annotation.UserIdInt; +import android.os.Environment; +import android.os.FileUtils; +import android.os.UserHandle; +import android.text.TextUtils; +import android.util.ArrayMap; +import android.util.AtomicFile; +import android.util.Slog; +import android.util.Xml; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.internal.util.FastXmlSerializer; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * Utility class to read/write subtype.xml. + */ +final class AdditionalSubtypeUtils { + private static final String TAG = "AdditionalSubtypeUtils"; + + private static final String SYSTEM_PATH = "system"; + private static final String INPUT_METHOD_PATH = "inputmethod"; + private static final String ADDITIONAL_SUBTYPES_FILE_NAME = "subtypes.xml"; + private static final String NODE_SUBTYPES = "subtypes"; + private static final String NODE_SUBTYPE = "subtype"; + private static final String NODE_IMI = "imi"; + private static final String ATTR_ID = "id"; + private static final String ATTR_LABEL = "label"; + private static final String ATTR_ICON = "icon"; + private static final String ATTR_IME_SUBTYPE_ID = "subtypeId"; + private static final String ATTR_IME_SUBTYPE_LOCALE = "imeSubtypeLocale"; + private static final String ATTR_IME_SUBTYPE_LANGUAGE_TAG = "languageTag"; + private static final String ATTR_IME_SUBTYPE_MODE = "imeSubtypeMode"; + private static final String ATTR_IME_SUBTYPE_EXTRA_VALUE = "imeSubtypeExtraValue"; + private static final String ATTR_IS_AUXILIARY = "isAuxiliary"; + private static final String ATTR_IS_ASCII_CAPABLE = "isAsciiCapable"; + + private AdditionalSubtypeUtils() { + } + + /** + * Returns a {@link File} that represents the directory at which subtype.xml will be placed. + * + * @param userId User ID with with subtype.xml path should be determined. + * @return {@link File} that represents the directory. + */ + @NonNull + private static File getInputMethodDir(@UserIdInt int userId) { + final File systemDir = userId == UserHandle.USER_SYSTEM + ? new File(Environment.getDataDirectory(), SYSTEM_PATH) + : Environment.getUserSystemDirectory(userId); + return new File(systemDir, INPUT_METHOD_PATH); + } + + /** + * Returns an {@link AtomicFile} to read/write additional subtype for the given user id. + * + * @param inputMethodDir Directory at which subtype.xml will be placed + * @return {@link AtomicFile} to be used to read/write additional subtype + */ + @NonNull + private static AtomicFile getAdditionalSubtypeFile(File inputMethodDir) { + final File subtypeFile = new File(inputMethodDir, ADDITIONAL_SUBTYPES_FILE_NAME); + return new AtomicFile(subtypeFile, "input-subtypes"); + } + + /** + * Write additional subtypes into "subtype.xml". + * + * <p>This method does not confer any data/file locking semantics. Caller must make sure that + * multiple threads are not calling this method at the same time for the same {@code userId}. + * </p> + * + * @param allSubtypes {@link ArrayMap} from IME ID to additional subtype list. Passing an empty + * map deletes the file. + * @param methodMap {@link ArrayMap} from IME ID to {@link InputMethodInfo}. + * @param userId The user ID to be associated with. + */ + static void save(ArrayMap<String, List<InputMethodSubtype>> allSubtypes, + ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) { + final File inputMethodDir = getInputMethodDir(userId); + + if (allSubtypes.isEmpty()) { + if (!inputMethodDir.exists()) { + // Even the parent directory doesn't exist. There is nothing to clean up. + return; + } + final AtomicFile subtypesFile = getAdditionalSubtypeFile(inputMethodDir); + if (subtypesFile.exists()) { + subtypesFile.delete(); + } + if (FileUtils.listFilesOrEmpty(inputMethodDir).length == 0) { + if (!inputMethodDir.delete()) { + Slog.e(TAG, "Failed to delete the empty parent directory " + inputMethodDir); + } + } + return; + } + + if (!inputMethodDir.exists() && !inputMethodDir.mkdirs()) { + Slog.e(TAG, "Failed to create a parent directory " + inputMethodDir); + return; + } + + // Safety net for the case that this function is called before methodMap is set. + final boolean isSetMethodMap = methodMap != null && methodMap.size() > 0; + FileOutputStream fos = null; + final AtomicFile subtypesFile = getAdditionalSubtypeFile(inputMethodDir); + try { + fos = subtypesFile.startWrite(); + final XmlSerializer out = new FastXmlSerializer(); + out.setOutput(fos, StandardCharsets.UTF_8.name()); + out.startDocument(null, true); + out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); + out.startTag(null, NODE_SUBTYPES); + for (String imiId : allSubtypes.keySet()) { + if (isSetMethodMap && !methodMap.containsKey(imiId)) { + Slog.w(TAG, "IME uninstalled or not valid.: " + imiId); + continue; + } + out.startTag(null, NODE_IMI); + out.attribute(null, ATTR_ID, imiId); + final List<InputMethodSubtype> subtypesList = allSubtypes.get(imiId); + final int numSubtypes = subtypesList.size(); + for (int i = 0; i < numSubtypes; ++i) { + final InputMethodSubtype subtype = subtypesList.get(i); + out.startTag(null, NODE_SUBTYPE); + if (subtype.hasSubtypeId()) { + out.attribute(null, ATTR_IME_SUBTYPE_ID, + String.valueOf(subtype.getSubtypeId())); + } + out.attribute(null, ATTR_ICON, String.valueOf(subtype.getIconResId())); + out.attribute(null, ATTR_LABEL, String.valueOf(subtype.getNameResId())); + out.attribute(null, ATTR_IME_SUBTYPE_LOCALE, subtype.getLocale()); + out.attribute(null, ATTR_IME_SUBTYPE_LANGUAGE_TAG, + subtype.getLanguageTag()); + out.attribute(null, ATTR_IME_SUBTYPE_MODE, subtype.getMode()); + out.attribute(null, ATTR_IME_SUBTYPE_EXTRA_VALUE, subtype.getExtraValue()); + out.attribute(null, ATTR_IS_AUXILIARY, + String.valueOf(subtype.isAuxiliary() ? 1 : 0)); + out.attribute(null, ATTR_IS_ASCII_CAPABLE, + String.valueOf(subtype.isAsciiCapable() ? 1 : 0)); + out.endTag(null, NODE_SUBTYPE); + } + out.endTag(null, NODE_IMI); + } + out.endTag(null, NODE_SUBTYPES); + out.endDocument(); + subtypesFile.finishWrite(fos); + } catch (java.io.IOException e) { + Slog.w(TAG, "Error writing subtypes", e); + if (fos != null) { + subtypesFile.failWrite(fos); + } + } + } + + /** + * Read additional subtypes from "subtype.xml". + * + * <p>This method does not confer any data/file locking semantics. Caller must make sure that + * multiple threads are not calling this method at the same time for the same {@code userId}. + * </p> + * + * @param allSubtypes {@link ArrayMap} from IME ID to additional subtype list. This parameter + * will be used to return the result. + * @param userId The user ID to be associated with. + */ + static void load(@NonNull ArrayMap<String, List<InputMethodSubtype>> allSubtypes, + @UserIdInt int userId) { + allSubtypes.clear(); + + final AtomicFile subtypesFile = getAdditionalSubtypeFile(getInputMethodDir(userId)); + if (!subtypesFile.exists()) { + // Not having the file means there is no additional subtype. + return; + } + try (FileInputStream fis = subtypesFile.openRead()) { + final XmlPullParser parser = Xml.newPullParser(); + parser.setInput(fis, StandardCharsets.UTF_8.name()); + int type = parser.getEventType(); + // Skip parsing until START_TAG + while (true) { + type = parser.next(); + if (type == XmlPullParser.START_TAG || type == XmlPullParser.END_DOCUMENT) { + break; + } + } + String firstNodeName = parser.getName(); + if (!NODE_SUBTYPES.equals(firstNodeName)) { + throw new XmlPullParserException("Xml doesn't start with subtypes"); + } + final int depth = parser.getDepth(); + String currentImiId = null; + ArrayList<InputMethodSubtype> tempSubtypesArray = null; + while (((type = parser.next()) != XmlPullParser.END_TAG + || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { + if (type != XmlPullParser.START_TAG) { + continue; + } + final String nodeName = parser.getName(); + if (NODE_IMI.equals(nodeName)) { + currentImiId = parser.getAttributeValue(null, ATTR_ID); + if (TextUtils.isEmpty(currentImiId)) { + Slog.w(TAG, "Invalid imi id found in subtypes.xml"); + continue; + } + tempSubtypesArray = new ArrayList<>(); + allSubtypes.put(currentImiId, tempSubtypesArray); + } else if (NODE_SUBTYPE.equals(nodeName)) { + if (TextUtils.isEmpty(currentImiId) || tempSubtypesArray == null) { + Slog.w(TAG, "IME uninstalled or not valid.: " + currentImiId); + continue; + } + final int icon = Integer.parseInt( + parser.getAttributeValue(null, ATTR_ICON)); + final int label = Integer.parseInt( + parser.getAttributeValue(null, ATTR_LABEL)); + final String imeSubtypeLocale = + parser.getAttributeValue(null, ATTR_IME_SUBTYPE_LOCALE); + final String languageTag = + parser.getAttributeValue(null, ATTR_IME_SUBTYPE_LANGUAGE_TAG); + final String imeSubtypeMode = + parser.getAttributeValue(null, ATTR_IME_SUBTYPE_MODE); + final String imeSubtypeExtraValue = + parser.getAttributeValue(null, ATTR_IME_SUBTYPE_EXTRA_VALUE); + final boolean isAuxiliary = "1".equals(String.valueOf( + parser.getAttributeValue(null, ATTR_IS_AUXILIARY))); + final boolean isAsciiCapable = "1".equals(String.valueOf( + parser.getAttributeValue(null, ATTR_IS_ASCII_CAPABLE))); + final InputMethodSubtype.InputMethodSubtypeBuilder + builder = new InputMethodSubtype.InputMethodSubtypeBuilder() + .setSubtypeNameResId(label) + .setSubtypeIconResId(icon) + .setSubtypeLocale(imeSubtypeLocale) + .setLanguageTag(languageTag) + .setSubtypeMode(imeSubtypeMode) + .setSubtypeExtraValue(imeSubtypeExtraValue) + .setIsAuxiliary(isAuxiliary) + .setIsAsciiCapable(isAsciiCapable); + final String subtypeIdString = + parser.getAttributeValue(null, ATTR_IME_SUBTYPE_ID); + if (subtypeIdString != null) { + builder.setSubtypeId(Integer.parseInt(subtypeIdString)); + } + tempSubtypesArray.add(builder.build()); + } + } + } catch (XmlPullParserException | IOException | NumberFormatException e) { + Slog.w(TAG, "Error reading subtypes", e); + } + } +} diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index fb6eaa0b85e6..5a7739c49b42 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -72,8 +72,6 @@ import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.Debug; -import android.os.Environment; -import android.os.FileUtils; import android.os.Handler; import android.os.IBinder; import android.os.IInterface; @@ -97,14 +95,12 @@ import android.text.TextUtils; import android.text.style.SuggestionSpan; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.AtomicFile; import android.util.EventLog; import android.util.LruCache; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Printer; import android.util.Slog; -import android.util.Xml; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.DisplayInfo; @@ -125,7 +121,6 @@ import android.view.inputmethod.InputMethod; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; -import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder; import android.widget.ArrayAdapter; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -147,7 +142,6 @@ import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; import com.android.internal.os.TransferPipe; import com.android.internal.util.DumpUtils; -import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.view.IInputContext; import com.android.internal.view.IInputMethod; @@ -164,21 +158,14 @@ import com.android.server.inputmethod.InputMethodUtils.InputMethodSettings; import com.android.server.statusbar.StatusBarManagerService; import com.android.server.wm.WindowManagerInternal; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.File; import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.lang.annotation.Retention; -import java.nio.charset.StandardCharsets; import java.security.InvalidParameterException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; @@ -314,7 +301,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final WindowManagerInternal mWindowManagerInternal; final HandlerCaller mCaller; final boolean mHasFeature; - private InputMethodFileManager mFileManager; + private final ArrayMap<String, List<InputMethodSubtype>> mAdditionalSubtypeMap = + new ArrayMap<>(); private final HardKeyboardListener mHardKeyboardListener; private final AppOpsManager mAppOpsManager; private final UserManager mUserManager; @@ -402,12 +390,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub }; private void restoreNonVrImeFromSettingsNoCheck() { - mIsVrImeStarted = false; // switch back to non-VR InputMethod from settings. synchronized (mMethodMap) { - final String lastInputId = mSettings.getSelectedInputMethod(); - setInputMethodLocked(lastInputId, - mSettings.getSelectedInputMethodSubtypeId(lastInputId)); + if (!mIsVrImeStarted) return; + mIsVrImeStarted = false; + updateFromSettingsLocked(false); } } @@ -553,10 +540,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ private InputMethodSubtype mCurrentSubtype; - // This list contains the pairs of InputMethodInfo and InputMethodSubtype. - private final ArrayMap<InputMethodInfo, ArrayList<InputMethodSubtype>> - mShortcutInputMethodsAndSubtypes = new ArrayMap<>(); - // Was the keyguard locked when this client became current? private boolean mCurClientInKeyguard; @@ -1224,7 +1207,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub int change = isPackageDisappearing(imi.getPackageName()); if (isPackageModified(imi.getPackageName())) { - mFileManager.deleteAllInputMethodSubtypes(imiId); + mAdditionalSubtypeMap.remove(imi.getId()); + AdditionalSubtypeUtils.save(mAdditionalSubtypeMap, mMethodMap, + mSettings.getCurrentUserId()); } if (change == PACKAGE_TEMPORARY_CHANGE || change == PACKAGE_PERMANENT_CHANGE) { @@ -1456,7 +1441,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mRes, context.getContentResolver(), mMethodMap, mMethodList, userId, !mSystemReady); updateCurrentProfileIds(); - mFileManager = new InputMethodFileManager(mMethodMap, userId); + AdditionalSubtypeUtils.load(mAdditionalSubtypeMap, userId); mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked( mSettings, context); // Register VR-state listener. @@ -1502,8 +1487,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub !mSystemReady || !mUserManager.isUserUnlockingOrUnlocked(newUserId); mSettings.switchCurrentUser(newUserId, useCopyOnWriteSettings); updateCurrentProfileIds(); - // InputMethodFileManager should be reset when the user is changed - mFileManager = new InputMethodFileManager(mMethodMap, newUserId); + // Additional subtypes should be reset when the user is changed + AdditionalSubtypeUtils.load(mAdditionalSubtypeMap, newUserId); final String defaultImiId = mSettings.getSelectedInputMethod(); if (DEBUG) Slog.d(TAG, "Switching user stage 2/3. newUserId=" + newUserId @@ -2535,7 +2520,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Slog.w(TAG, "Unknown input method from prefs: " + id, e); resetCurrentMethodAndClient(UnbindReason.SWITCH_IME_FAILED); } - mShortcutInputMethodsAndSubtypes.clear(); } else { // There is no longer an input method set, so stop any current one. resetCurrentMethodAndClient(UnbindReason.NO_IME); @@ -3082,20 +3066,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - @Override - public void setInputMethod(IBinder token, String id) { + @BinderThread + private void setInputMethod(IBinder token, String id) { synchronized (mMethodMap) { - if (!calledFromValidUserLocked()) { + if (!calledWithValidTokenLocked(token)) { return; } setInputMethodWithSubtypeIdLocked(token, id, NOT_A_SUBTYPE_ID); } } - @Override - public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) { + @BinderThread + private void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) { synchronized (mMethodMap) { - if (!calledFromValidUserLocked()) { + if (!calledWithValidTokenLocked(token)) { return; } if (subtype != null) { @@ -3256,6 +3240,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // By this IPC call, only a process which shares the same uid with the IME can add // additional input method subtypes to the IME. if (TextUtils.isEmpty(imiId) || subtypes == null) return; + final ArrayList<InputMethodSubtype> toBeAdded = new ArrayList<>(); + for (InputMethodSubtype subtype : subtypes) { + if (!toBeAdded.contains(subtype)) { + toBeAdded.add(subtype); + } else { + Slog.w(TAG, "Duplicated subtype definition found: " + + subtype.getLocale() + ", " + subtype.getMode()); + } + } synchronized (mMethodMap) { if (!calledFromValidUserLocked()) { return; @@ -3277,10 +3270,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub for (int i = 0; i < packageNum; ++i) { if (packageInfos[i].equals(imi.getPackageName())) { if (subtypes.length > 0) { - mFileManager.addInputMethodSubtypes(imi, subtypes); + mAdditionalSubtypeMap.put(imi.getId(), toBeAdded); } else { - mFileManager.deleteAllInputMethodSubtypes(imi.getId()); + mAdditionalSubtypeMap.remove(imi.getId()); } + AdditionalSubtypeUtils.save(mAdditionalSubtypeMap, mMethodMap, + mSettings.getCurrentUserId()); final long ident = Binder.clearCallingIdentity(); try { buildInputMethodListLocked(false /* resetDefaultEnabledIme */); @@ -3626,34 +3621,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return false; } - @GuardedBy("mMethodMap") - void buildInputMethodListLocked(boolean resetDefaultEnabledIme) { - if (DEBUG) { - Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme - + " \n ------ caller=" + Debug.getCallers(10)); - } - if (!mSystemReady) { - Slog.e(TAG, "buildInputMethodListLocked is not allowed until system is ready"); - return; - } - mMethodList.clear(); - mMethodMap.clear(); - mMethodMapUpdateCount++; - mMyPackageMonitor.clearKnownImePackageNamesLocked(); - - // Use for queryIntentServicesAsUser - final PackageManager pm = mContext.getPackageManager(); + static void queryInputMethodServicesInternal(Context context, + @UserIdInt int userId, ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap, + ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList) { + methodList.clear(); + methodMap.clear(); // Note: We do not specify PackageManager.MATCH_ENCRYPTION_* flags here because the default // behavior of PackageManager is exactly what we want. It by default picks up appropriate // services depending on the unlock state for the specified user. - final List<ResolveInfo> services = pm.queryIntentServicesAsUser( + final List<ResolveInfo> services = context.getPackageManager().queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE), PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, - mSettings.getCurrentUserId()); + userId); + + methodList.ensureCapacity(services.size()); + methodMap.ensureCapacity(services.size()); - final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap = - mFileManager.getAllAdditionalInputMethodSubtypes(); for (int i = 0; i < services.size(); ++i) { ResolveInfo ri = services.get(i); ServiceInfo si = ri.serviceInfo; @@ -3667,20 +3651,35 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.d(TAG, "Checking " + imeId); - final List<InputMethodSubtype> additionalSubtypes = additionalSubtypeMap.get(imeId); try { - InputMethodInfo p = new InputMethodInfo(mContext, ri, additionalSubtypes); - mMethodList.add(p); - final String id = p.getId(); - mMethodMap.put(id, p); - + final InputMethodInfo imi = new InputMethodInfo(context, ri, + additionalSubtypeMap.get(imeId)); + methodList.add(imi); + methodMap.put(imi.getId(), imi); if (DEBUG) { - Slog.d(TAG, "Found an input method " + p); + Slog.d(TAG, "Found an input method " + imi); } } catch (Exception e) { Slog.wtf(TAG, "Unable to load input method " + imeId, e); } } + } + + @GuardedBy("mMethodMap") + void buildInputMethodListLocked(boolean resetDefaultEnabledIme) { + if (DEBUG) { + Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme + + " \n ------ caller=" + Debug.getCallers(10)); + } + if (!mSystemReady) { + Slog.e(TAG, "buildInputMethodListLocked is not allowed until system is ready"); + return; + } + mMethodMapUpdateCount++; + mMyPackageMonitor.clearKnownImePackageNamesLocked(); + + queryInputMethodServicesInternal(mContext, mSettings.getCurrentUserId(), + mAdditionalSubtypeMap, mMethodMap, mMethodList); // Construct the set of possible IME packages for onPackageChanged() to avoid false // negatives when the package state remains to be the same but only the component state is @@ -3689,9 +3688,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Here we intentionally use PackageManager.MATCH_DISABLED_COMPONENTS since the purpose // of this query is to avoid false negatives. PackageManager.MATCH_ALL could be more // conservative, but it seems we cannot use it for now (Issue 35176630). - final List<ResolveInfo> allInputMethodServices = pm.queryIntentServicesAsUser( - new Intent(InputMethod.SERVICE_INTERFACE), - PackageManager.MATCH_DISABLED_COMPONENTS, mSettings.getCurrentUserId()); + final List<ResolveInfo> allInputMethodServices = + mContext.getPackageManager().queryIntentServicesAsUser( + new Intent(InputMethod.SERVICE_INTERFACE), + PackageManager.MATCH_DISABLED_COMPONENTS, mSettings.getCurrentUserId()); final int N = allInputMethodServices.size(); for (int i = 0; i < N; ++i) { final ServiceInfo si = allInputMethodServices.get(i).serviceInfo; @@ -4089,86 +4089,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false); } - // If there are no selected shortcuts, tries finding the most applicable ones. - private Pair<InputMethodInfo, InputMethodSubtype> - findLastResortApplicableShortcutInputMethodAndSubtypeLocked(String mode) { - List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked(); - InputMethodInfo mostApplicableIMI = null; - InputMethodSubtype mostApplicableSubtype = null; - boolean foundInSystemIME = false; - - // Search applicable subtype for each InputMethodInfo - for (InputMethodInfo imi: imis) { - final String imiId = imi.getId(); - if (foundInSystemIME && !imiId.equals(mCurMethodId)) { - continue; - } - InputMethodSubtype subtype = null; - final List<InputMethodSubtype> enabledSubtypes = - mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true); - // 1. Search by the current subtype's locale from enabledSubtypes. - if (mCurrentSubtype != null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, enabledSubtypes, mode, mCurrentSubtype.getLocale(), false); - } - // 2. Search by the system locale from enabledSubtypes. - // 3. Search the first enabled subtype matched with mode from enabledSubtypes. - if (subtype == null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, enabledSubtypes, mode, null, true); - } - final ArrayList<InputMethodSubtype> overridingImplicitlyEnabledSubtypes = - InputMethodUtils.getOverridingImplicitlyEnabledSubtypes(imi, mode); - final ArrayList<InputMethodSubtype> subtypesForSearch = - overridingImplicitlyEnabledSubtypes.isEmpty() - ? InputMethodUtils.getSubtypes(imi) - : overridingImplicitlyEnabledSubtypes; - // 4. Search by the current subtype's locale from all subtypes. - if (subtype == null && mCurrentSubtype != null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, subtypesForSearch, mode, mCurrentSubtype.getLocale(), false); - } - // 5. Search by the system locale from all subtypes. - // 6. Search the first enabled subtype matched with mode from all subtypes. - if (subtype == null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, subtypesForSearch, mode, null, true); - } - if (subtype != null) { - if (imiId.equals(mCurMethodId)) { - // The current input method is the most applicable IME. - mostApplicableIMI = imi; - mostApplicableSubtype = subtype; - break; - } else if (!foundInSystemIME) { - // The system input method is 2nd applicable IME. - mostApplicableIMI = imi; - mostApplicableSubtype = subtype; - if ((imi.getServiceInfo().applicationInfo.flags - & ApplicationInfo.FLAG_SYSTEM) != 0) { - foundInSystemIME = true; - } - } - } - } - if (DEBUG) { - if (mostApplicableIMI != null) { - Slog.w(TAG, "Most applicable shortcut input method was:" - + mostApplicableIMI.getId()); - if (mostApplicableSubtype != null) { - Slog.w(TAG, "Most applicable shortcut input method subtype was:" - + "," + mostApplicableSubtype.getMode() + "," - + mostApplicableSubtype.getLocale()); - } - } - } - if (mostApplicableIMI != null) { - return new Pair<> (mostApplicableIMI, mostApplicableSubtype); - } else { - return null; - } - } - /** * @return Return the current subtype of this input method. */ @@ -4222,35 +4142,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mCurrentSubtype; } - // TODO: We should change the return type from List to List<Parcelable> - @SuppressWarnings("rawtypes") - @Override - public List getShortcutInputMethodsAndSubtypes() { - synchronized (mMethodMap) { - ArrayList<Object> ret = new ArrayList<>(); - if (mShortcutInputMethodsAndSubtypes.size() == 0) { - // If there are no selected shortcut subtypes, the framework will try to find - // the most applicable subtype from all subtypes whose mode is - // SUBTYPE_MODE_VOICE. This is an exceptional case, so we will hardcode the mode. - Pair<InputMethodInfo, InputMethodSubtype> info = - findLastResortApplicableShortcutInputMethodAndSubtypeLocked( - InputMethodUtils.SUBTYPE_MODE_VOICE); - if (info != null) { - ret.add(info.first); - ret.add(info.second); - } - return ret; - } - for (InputMethodInfo imi: mShortcutInputMethodsAndSubtypes.keySet()) { - ret.add(imi); - for (InputMethodSubtype subtype: mShortcutInputMethodsAndSubtypes.get(imi)) { - ret.add(subtype); - } - } - return ret; - } - } - @Override public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { synchronized (mMethodMap) { @@ -4270,231 +4161,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - // TODO: Cache the state for each user and reset when the cached user is removed. - private static class InputMethodFileManager { - private static final String SYSTEM_PATH = "system"; - private static final String INPUT_METHOD_PATH = "inputmethod"; - private static final String ADDITIONAL_SUBTYPES_FILE_NAME = "subtypes.xml"; - private static final String NODE_SUBTYPES = "subtypes"; - private static final String NODE_SUBTYPE = "subtype"; - private static final String NODE_IMI = "imi"; - private static final String ATTR_ID = "id"; - private static final String ATTR_LABEL = "label"; - private static final String ATTR_ICON = "icon"; - private static final String ATTR_IME_SUBTYPE_ID = "subtypeId"; - private static final String ATTR_IME_SUBTYPE_LOCALE = "imeSubtypeLocale"; - private static final String ATTR_IME_SUBTYPE_LANGUAGE_TAG = "languageTag"; - private static final String ATTR_IME_SUBTYPE_MODE = "imeSubtypeMode"; - private static final String ATTR_IME_SUBTYPE_EXTRA_VALUE = "imeSubtypeExtraValue"; - private static final String ATTR_IS_AUXILIARY = "isAuxiliary"; - private static final String ATTR_IS_ASCII_CAPABLE = "isAsciiCapable"; - private final AtomicFile mAdditionalInputMethodSubtypeFile; - private final ArrayMap<String, InputMethodInfo> mMethodMap; - private final ArrayMap<String, List<InputMethodSubtype>> mAdditionalSubtypesMap = - new ArrayMap<>(); - InputMethodFileManager(ArrayMap<String, InputMethodInfo> methodMap, int userId) { - if (methodMap == null) { - throw new NullPointerException("methodMap is null"); - } - mMethodMap = methodMap; - final File systemDir = userId == UserHandle.USER_SYSTEM - ? new File(Environment.getDataDirectory(), SYSTEM_PATH) - : Environment.getUserSystemDirectory(userId); - final File inputMethodDir = new File(systemDir, INPUT_METHOD_PATH); - final File subtypeFile = new File(inputMethodDir, ADDITIONAL_SUBTYPES_FILE_NAME); - mAdditionalInputMethodSubtypeFile = new AtomicFile(subtypeFile, "input-subtypes"); - readAdditionalInputMethodSubtypes(mAdditionalSubtypesMap, - mAdditionalInputMethodSubtypeFile); - } - - private void deleteAllInputMethodSubtypes(String imiId) { - synchronized (mMethodMap) { - mAdditionalSubtypesMap.remove(imiId); - writeAdditionalInputMethodSubtypes( - mAdditionalSubtypesMap, mAdditionalInputMethodSubtypeFile, mMethodMap); - } - } - - public void addInputMethodSubtypes( - InputMethodInfo imi, InputMethodSubtype[] additionalSubtypes) { - synchronized (mMethodMap) { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); - final int N = additionalSubtypes.length; - for (int i = 0; i < N; ++i) { - final InputMethodSubtype subtype = additionalSubtypes[i]; - if (!subtypes.contains(subtype)) { - subtypes.add(subtype); - } else { - Slog.w(TAG, "Duplicated subtype definition found: " - + subtype.getLocale() + ", " + subtype.getMode()); - } - } - mAdditionalSubtypesMap.put(imi.getId(), subtypes); - writeAdditionalInputMethodSubtypes( - mAdditionalSubtypesMap, mAdditionalInputMethodSubtypeFile, mMethodMap); - } - } - - public ArrayMap<String, List<InputMethodSubtype>> getAllAdditionalInputMethodSubtypes() { - synchronized (mMethodMap) { - return mAdditionalSubtypesMap; - } - } - - private static void writeAdditionalInputMethodSubtypes( - ArrayMap<String, List<InputMethodSubtype>> allSubtypes, AtomicFile subtypesFile, - ArrayMap<String, InputMethodInfo> methodMap) { - if (allSubtypes.isEmpty()) { - if (subtypesFile.exists()) { - subtypesFile.delete(); - } - final File parentDir = subtypesFile.getBaseFile().getParentFile(); - if (parentDir != null && FileUtils.listFilesOrEmpty(parentDir).length == 0) { - if (!parentDir.delete()) { - Slog.e(TAG, "Failed to delete the empty parent directory " + parentDir); - } - } - return; - } - - final File parentDir = subtypesFile.getBaseFile().getParentFile(); - if (!parentDir.exists() && !parentDir.mkdirs()) { - Slog.e(TAG, "Failed to create a parent directory " + parentDir); - return; - } - - // Safety net for the case that this function is called before methodMap is set. - final boolean isSetMethodMap = methodMap != null && methodMap.size() > 0; - FileOutputStream fos = null; - try { - fos = subtypesFile.startWrite(); - final XmlSerializer out = new FastXmlSerializer(); - out.setOutput(fos, StandardCharsets.UTF_8.name()); - out.startDocument(null, true); - out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - out.startTag(null, NODE_SUBTYPES); - for (String imiId : allSubtypes.keySet()) { - if (isSetMethodMap && !methodMap.containsKey(imiId)) { - Slog.w(TAG, "IME uninstalled or not valid.: " + imiId); - continue; - } - out.startTag(null, NODE_IMI); - out.attribute(null, ATTR_ID, imiId); - final List<InputMethodSubtype> subtypesList = allSubtypes.get(imiId); - final int N = subtypesList.size(); - for (int i = 0; i < N; ++i) { - final InputMethodSubtype subtype = subtypesList.get(i); - out.startTag(null, NODE_SUBTYPE); - if (subtype.hasSubtypeId()) { - out.attribute(null, ATTR_IME_SUBTYPE_ID, - String.valueOf(subtype.getSubtypeId())); - } - out.attribute(null, ATTR_ICON, String.valueOf(subtype.getIconResId())); - out.attribute(null, ATTR_LABEL, String.valueOf(subtype.getNameResId())); - out.attribute(null, ATTR_IME_SUBTYPE_LOCALE, subtype.getLocale()); - out.attribute(null, ATTR_IME_SUBTYPE_LANGUAGE_TAG, - subtype.getLanguageTag()); - out.attribute(null, ATTR_IME_SUBTYPE_MODE, subtype.getMode()); - out.attribute(null, ATTR_IME_SUBTYPE_EXTRA_VALUE, subtype.getExtraValue()); - out.attribute(null, ATTR_IS_AUXILIARY, - String.valueOf(subtype.isAuxiliary() ? 1 : 0)); - out.attribute(null, ATTR_IS_ASCII_CAPABLE, - String.valueOf(subtype.isAsciiCapable() ? 1 : 0)); - out.endTag(null, NODE_SUBTYPE); - } - out.endTag(null, NODE_IMI); - } - out.endTag(null, NODE_SUBTYPES); - out.endDocument(); - subtypesFile.finishWrite(fos); - } catch (java.io.IOException e) { - Slog.w(TAG, "Error writing subtypes", e); - if (fos != null) { - subtypesFile.failWrite(fos); - } - } - } - - private static void readAdditionalInputMethodSubtypes( - ArrayMap<String, List<InputMethodSubtype>> allSubtypes, AtomicFile subtypesFile) { - if (allSubtypes == null || subtypesFile == null) return; - allSubtypes.clear(); - if (!subtypesFile.exists()) { - // Not having the file means there is no additional subtype. - return; - } - try (final FileInputStream fis = subtypesFile.openRead()) { - final XmlPullParser parser = Xml.newPullParser(); - parser.setInput(fis, StandardCharsets.UTF_8.name()); - int type = parser.getEventType(); - // Skip parsing until START_TAG - while ((type = parser.next()) != XmlPullParser.START_TAG - && type != XmlPullParser.END_DOCUMENT) {} - String firstNodeName = parser.getName(); - if (!NODE_SUBTYPES.equals(firstNodeName)) { - throw new XmlPullParserException("Xml doesn't start with subtypes"); - } - final int depth =parser.getDepth(); - String currentImiId = null; - ArrayList<InputMethodSubtype> tempSubtypesArray = null; - while (((type = parser.next()) != XmlPullParser.END_TAG - || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { - if (type != XmlPullParser.START_TAG) - continue; - final String nodeName = parser.getName(); - if (NODE_IMI.equals(nodeName)) { - currentImiId = parser.getAttributeValue(null, ATTR_ID); - if (TextUtils.isEmpty(currentImiId)) { - Slog.w(TAG, "Invalid imi id found in subtypes.xml"); - continue; - } - tempSubtypesArray = new ArrayList<>(); - allSubtypes.put(currentImiId, tempSubtypesArray); - } else if (NODE_SUBTYPE.equals(nodeName)) { - if (TextUtils.isEmpty(currentImiId) || tempSubtypesArray == null) { - Slog.w(TAG, "IME uninstalled or not valid.: " + currentImiId); - continue; - } - final int icon = Integer.parseInt( - parser.getAttributeValue(null, ATTR_ICON)); - final int label = Integer.parseInt( - parser.getAttributeValue(null, ATTR_LABEL)); - final String imeSubtypeLocale = - parser.getAttributeValue(null, ATTR_IME_SUBTYPE_LOCALE); - final String languageTag = - parser.getAttributeValue(null, ATTR_IME_SUBTYPE_LANGUAGE_TAG); - final String imeSubtypeMode = - parser.getAttributeValue(null, ATTR_IME_SUBTYPE_MODE); - final String imeSubtypeExtraValue = - parser.getAttributeValue(null, ATTR_IME_SUBTYPE_EXTRA_VALUE); - final boolean isAuxiliary = "1".equals(String.valueOf( - parser.getAttributeValue(null, ATTR_IS_AUXILIARY))); - final boolean isAsciiCapable = "1".equals(String.valueOf( - parser.getAttributeValue(null, ATTR_IS_ASCII_CAPABLE))); - final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder() - .setSubtypeNameResId(label) - .setSubtypeIconResId(icon) - .setSubtypeLocale(imeSubtypeLocale) - .setLanguageTag(languageTag) - .setSubtypeMode(imeSubtypeMode) - .setSubtypeExtraValue(imeSubtypeExtraValue) - .setIsAuxiliary(isAuxiliary) - .setIsAsciiCapable(isAsciiCapable); - final String subtypeIdString = - parser.getAttributeValue(null, ATTR_IME_SUBTYPE_ID); - if (subtypeIdString != null) { - builder.setSubtypeId(Integer.parseInt(subtypeIdString)); - } - tempSubtypesArray.add(builder.build()); - } - } - } catch (XmlPullParserException | IOException | NumberFormatException e) { - Slog.w(TAG, "Error reading subtypes", e); - return; - } - } - } - private static final class LocalServiceImpl extends InputMethodManagerInternal { @NonNull private final InputMethodManagerService mService; @@ -4696,6 +4362,25 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) throws RemoteException { + final int callingUid = Binder.getCallingUid(); + // Reject any incoming calls from non-shell users, including ones from the system user. + if (callingUid != Process.ROOT_UID && callingUid != Process.SHELL_UID) { + // Note that Binder#onTransact() will automatically close "in", "out", and "err" when + // returned from this method, hence there is no need to close those FDs. + // "resultReceiver" is the only thing that needs to be taken care of here. + if (resultReceiver != null) { + resultReceiver.send(ShellCommandResult.FAILURE, null); + } + final String errorMsg = "InputMethodManagerService does not support shell commands from" + + " non-shell users. callingUid=" + callingUid + + " args=" + Arrays.toString(args); + if (Process.isCoreUid(callingUid)) { + // Let's not crash the calling process if the caller is one of core components. + Slog.e(TAG, errorMsg); + return; + } + throw new SecurityException(errorMsg); + } new ShellCommandImpl(this).exec( this, in, out, err, args, callback, resultReceiver); } @@ -4708,10 +4393,33 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mService = service; } + @RequiresPermission(allOf = { + Manifest.permission.DUMP, + Manifest.permission.INTERACT_ACROSS_USERS_FULL, + Manifest.permission.WRITE_SECURE_SETTINGS, + }) @BinderThread @ShellCommandResult @Override public int onCommand(@Nullable String cmd) { + // For shell command, require all the permissions here in favor of code simplicity. + Arrays.asList( + Manifest.permission.DUMP, + Manifest.permission.INTERACT_ACROSS_USERS_FULL, + Manifest.permission.WRITE_SECURE_SETTINGS + ).forEach(permission -> mService.mContext.enforceCallingPermission(permission, null)); + + final long identity = Binder.clearCallingIdentity(); + try { + return onCommandWithSystemIdentity(cmd); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @BinderThread + @ShellCommandResult + private int onCommandWithSystemIdentity(@Nullable String cmd) { if ("refresh_debug_properties".equals(cmd)) { return refreshDebugProperties(); } @@ -4856,29 +4564,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ @BinderThread @ShellCommandResult - @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) private int handleShellCommandEnableDisableInputMethod( @NonNull ShellCommand shellCommand, boolean enabled) { final String id = shellCommand.getNextArgRequired(); final boolean previouslyEnabled; synchronized (mMethodMap) { - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.WRITE_SECURE_SETTINGS) - != PackageManager.PERMISSION_GRANTED) { - shellCommand.getErrPrintWriter().print( - "Caller must have WRITE_SECURE_SETTINGS permission"); - throw new SecurityException( - "Requires permission " - + android.Manifest.permission.WRITE_SECURE_SETTINGS); - } - - final long ident = Binder.clearCallingIdentity(); - try { - previouslyEnabled = setInputMethodEnabledLocked(id, enabled); - } finally { - Binder.restoreCallingIdentity(ident); - } + previouslyEnabled = setInputMethodEnabledLocked(id, enabled); } final PrintWriter pr = shellCommand.getOutPrintWriter(); pr.print("Input method "); @@ -4898,7 +4590,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @ShellCommandResult private int handleShellCommandSetInputMethod(@NonNull ShellCommand shellCommand) { final String id = shellCommand.getNextArgRequired(); - setInputMethod(null, id); + synchronized (mMethodMap) { + setInputMethodLocked(id, NOT_A_SUBTYPE_ID); + } final PrintWriter pr = shellCommand.getOutPrintWriter(); pr.print("Input method "); pr.print(id); @@ -4913,58 +4607,29 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ @BinderThread @ShellCommandResult - @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) private int handleShellCommandResetInputMethod(@NonNull ShellCommand shellCommand) { synchronized (mMethodMap) { - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.WRITE_SECURE_SETTINGS) - != PackageManager.PERMISSION_GRANTED) { - shellCommand.getErrPrintWriter().print( - "Caller must have WRITE_SECURE_SETTINGS permission"); - throw new SecurityException( - "Requires permission " - + android.Manifest.permission.WRITE_SECURE_SETTINGS); - } final String nextIme; final List<InputMethodInfo> nextEnabledImes; - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mMethodMap) { - hideCurrentInputLocked(0, null); - unbindCurrentMethodLocked(); - // Reset the current IME - resetSelectedInputMethodAndSubtypeLocked(null); - // Also reset the settings of the current IME - mSettings.putSelectedInputMethod(null); - // Disable all enabled IMEs. - { - final ArrayList<InputMethodInfo> enabledImes = - mSettings.getEnabledInputMethodListLocked(); - final int N = enabledImes.size(); - for (int i = 0; i < N; ++i) { - setInputMethodEnabledLocked(enabledImes.get(i).getId(), false); - } - } - // Re-enable with default enabled IMEs. - { - final ArrayList<InputMethodInfo> defaultEnabledIme = - InputMethodUtils.getDefaultEnabledImes(mContext, mMethodList); - final int N = defaultEnabledIme.size(); - for (int i = 0; i < N; ++i) { - setInputMethodEnabledLocked(defaultEnabledIme.get(i).getId(), true); - } - } - updateInputMethodsFromSettingsLocked(true /* enabledMayChange */); - InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager, - mSettings.getEnabledInputMethodListLocked(), - mSettings.getCurrentUserId(), - mContext.getBasePackageName()); - nextIme = mSettings.getSelectedInputMethod(); - nextEnabledImes = getEnabledInputMethodList(); - } - } finally { - Binder.restoreCallingIdentity(ident); - } + hideCurrentInputLocked(0, null); + unbindCurrentMethodLocked(); + // Reset the current IME + resetSelectedInputMethodAndSubtypeLocked(null); + // Also reset the settings of the current IME + mSettings.putSelectedInputMethod(null); + // Disable all enabled IMEs. + mSettings.getEnabledInputMethodListLocked().forEach( + imi -> setInputMethodEnabledLocked(imi.getId(), false)); + // Re-enable with default enabled IMEs. + InputMethodUtils.getDefaultEnabledImes(mContext, mMethodList).forEach( + imi -> setInputMethodEnabledLocked(imi.getId(), true)); + updateInputMethodsFromSettingsLocked(true /* enabledMayChange */); + InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager, + mSettings.getEnabledInputMethodListLocked(), + mSettings.getCurrentUserId(), + mContext.getBasePackageName()); + nextIme = mSettings.getSelectedInputMethod(); + nextEnabledImes = getEnabledInputMethodList(); final PrintWriter pr = shellCommand.getOutPrintWriter(); pr.println("Reset current and enabled IMEs"); pr.println("Newly selected IME:"); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java index 8e3f35111268..1137bf967d24 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java @@ -38,11 +38,11 @@ import android.util.Slog; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodSubtype; import android.view.textservice.SpellCheckerInfo; -import android.view.textservice.TextServicesManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.StartInputFlags; +import com.android.server.textservices.TextServicesManagerInternal; import java.util.ArrayList; import java.util.Arrays; @@ -63,7 +63,6 @@ final class InputMethodUtils { public static final int NOT_A_SUBTYPE_ID = -1; public static final String SUBTYPE_MODE_ANY = null; public static final String SUBTYPE_MODE_KEYBOARD = "keyboard"; - public static final String SUBTYPE_MODE_VOICE = "voice"; private static final String TAG = "InputMethodUtils"; private static final Locale ENGLISH_LOCALE = new Locale("en"); private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID); @@ -375,19 +374,6 @@ final class InputMethodUtils { return subtypes; } - public static ArrayList<InputMethodSubtype> getOverridingImplicitlyEnabledSubtypes( - InputMethodInfo imi, String mode) { - ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); - final int subtypeCount = imi.getSubtypeCount(); - for (int i = 0; i < subtypeCount; ++i) { - final InputMethodSubtype subtype = imi.getSubtypeAt(i); - if (subtype.overridesImplicitlyEnabledSubtype() && subtype.getMode().equals(mode)) { - subtypes.add(subtype); - } - } - return subtypes; - } - public static InputMethodInfo getMostApplicableDefaultIME(List<InputMethodInfo> enabledImes) { if (enabledImes == null || enabledImes.isEmpty()) { return null; @@ -641,7 +627,7 @@ final class InputMethodUtils { } // Only the current spell checker should be treated as an enabled one. final SpellCheckerInfo currentSpellChecker = - TextServicesManager.getInstance().getCurrentSpellChecker(); + TextServicesManagerInternal.get().getCurrentSpellCheckerForUser(userId); for (final String packageName : systemImesDisabledUntilUsed) { if (DEBUG) { Slog.d(TAG, "check " + packageName); diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 5edb5c8e3286..98ed3ea92fa1 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -50,7 +50,6 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; -import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; @@ -65,6 +64,7 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodSubtype; +import android.view.inputmethod.InputMethodSystemProperty; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.IMultiClientInputMethod; @@ -99,20 +99,6 @@ public final class MultiClientInputMethodManagerService { static final String TAG = "MultiClientInputMethodManagerService"; static final boolean DEBUG = false; - /** - * System property key for the production use. The value must be either empty or a valid - * (flattened) component name of the multi-client IME. - */ - private static final String PROP_PROD_MULTI_CLIENT_IME = "ro.sys.multi_client_ime"; - - /** - * System property key for debugging purpose. The value must be either empty or a valid - * (flattened) component name of the multi-client IME. - * - * <p>This value will be ignored when {@link Build#IS_DEBUGGABLE} returns {@code false}</p> - */ - private static final String PROP_DEBUG_MULTI_CLIENT_IME = "persist.debug.multi_client_ime"; - private static final long RECONNECT_DELAY_MSEC = 1000; /** @@ -125,36 +111,8 @@ public final class MultiClientInputMethodManagerService { | Context.BIND_NOT_FOREGROUND | Context.BIND_FOREGROUND_SERVICE; - /** - * Inner class to read system property on demand, not when - * {@link MultiClientInputMethodManagerService} class is accessed. - */ - private static final class ImeComponentName { - private static ComponentName evaluate() { - if (Build.IS_DEBUGGABLE) { - // If debuggable, allow developers to override the multi-client IME component name - // with a different (writable) key. - final ComponentName debugIme = ComponentName.unflattenFromString( - SystemProperties.get(PROP_DEBUG_MULTI_CLIENT_IME, "")); - if (debugIme != null) { - return debugIme; - } - } - return ComponentName.unflattenFromString( - SystemProperties.get(PROP_PROD_MULTI_CLIENT_IME, "")); - } - - /** - * {@link ComponentName} of the multi-client IME. {@code null} when the system is not - * configured to use multi-client IME. - */ - @Nullable - static final ComponentName sValue = evaluate(); - } - - public static boolean isConfiguredToUse() { - return ImeComponentName.sValue != null; - } + private static final ComponentName sImeComponentName = + InputMethodSystemProperty.sMultiClientImeComponentName; private static void reportNotSupported() { if (DEBUG) { @@ -270,10 +228,10 @@ public final class MultiClientInputMethodManagerService { return; } - final InputMethodInfo imi = queryInputMethod(mContext, userId, ImeComponentName.sValue); + final InputMethodInfo imi = queryInputMethod(mContext, userId, sImeComponentName); if (imi == null) { Slog.w(TAG, "Multi-client InputMethod is not found. component=" - + ImeComponentName.sValue); + + sImeComponentName); synchronized (data.mLock) { switch (data.mState) { case PerUserState.USER_LOCKED: @@ -518,9 +476,9 @@ public final class MultiClientInputMethodManagerService { return; } final String packageName = uri.getSchemeSpecificPart(); - if (ImeComponentName.sValue == null + if (sImeComponentName == null || packageName == null - || !TextUtils.equals(ImeComponentName.sValue.getPackageName(), packageName)) { + || !TextUtils.equals(sImeComponentName.getPackageName(), packageName)) { return; } final int userId = UserHandle.getUserId(intent.getIntExtra(Intent.EXTRA_UID, 0)); @@ -1303,13 +1261,6 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public List getShortcutInputMethodsAndSubtypes() { - reportNotSupported(); - return null; - } - - @BinderThread - @Override public boolean showSoftInput( IInputMethodClient client, int flags, ResultReceiver resultReceiver) { final int callingUid = Binder.getCallingUid(); @@ -1562,18 +1513,6 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void setInputMethod(IBinder token, String id) { - reportNotSupported(); - } - - @BinderThread - @Override - public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) { - reportNotSupported(); - } - - @BinderThread - @Override public void registerSuggestionSpansForNotification(SuggestionSpan[] suggestionSpans) { reportNotSupported(); } diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 9c6cb20b88b6..05d77ab5867e 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -177,10 +177,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static final int AGPS_SUPL_MODE_MSA = 0x02; private static final int AGPS_SUPL_MODE_MSB = 0x01; - // these need to match AGnssType enum in IAGnssCallback.hal - private static final int AGPS_TYPE_SUPL = 1; - private static final int AGPS_TYPE_C2K = 2; - // Handler messages private static final int CHECK_LOCATION = 1; private static final int ENABLE = 2; @@ -192,7 +188,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static final int ADD_LISTENER = 8; private static final int REMOVE_LISTENER = 9; private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11; - private static final int SUBSCRIPTION_OR_SIM_CHANGED = 12; + private static final int SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED = 12; private static final int INITIALIZE_HANDLER = 13; private static final int REQUEST_SUPL_CONNECTION = 14; private static final int RELEASE_SUPL_CONNECTION = 15; @@ -415,9 +411,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; - // SIM/Carrier info. - private final static String SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED"; - // Persist property for LPP_PROFILE private final static String LPP_PROFILE = "persist.sys.gps.lpp"; @@ -487,18 +480,20 @@ public class GnssLocationProvider extends AbstractLocationProvider implements case Intent.ACTION_SCREEN_ON: updateLowPowerMode(); break; - case SIM_STATE_CHANGED: - subscriptionOrSimChanged(context); + case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: + subscriptionOrCarrierConfigChanged(context); break; } } }; + // TODO(b/119326010): replace OnSubscriptionsChangedListener with + // ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED broadcast reseiver. private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener = new OnSubscriptionsChangedListener() { @Override public void onSubscriptionsChanged() { - sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null); + sendMessage(SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED, 0, null); } }; @@ -510,7 +505,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mHandler.post(() -> native_set_satellite_blacklist(constellations, svids)); } - private void subscriptionOrSimChanged(Context context) { + private void subscriptionOrCarrierConfigChanged(Context context) { if (DEBUG) Log.d(TAG, "received SIM related action: "); TelephonyManager phone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); @@ -525,12 +520,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements PersistableBundle b = configManager.getConfig(); if (b != null) { isKeepLppProfile = - b.getBoolean(CarrierConfigManager.KEY_PERSIST_LPP_MODE_BOOL); + b.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL); } } if (isKeepLppProfile) { // load current properties for the carrier - loadPropertiesFromResource(context, mProperties); + loadPropertiesFromCarrierConfig(context, mProperties); String lpp_profile = mProperties.getProperty("LPP_PROFILE"); // set the persist property LPP_PROFILE for the value if (lpp_profile != null) { @@ -575,7 +570,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private void reloadGpsProperties(Context context, Properties properties) { if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + properties.size()); - loadPropertiesFromResource(context, properties); + loadPropertiesFromCarrierConfig(context, properties); String lpp_prof = SystemProperties.get(LPP_PROFILE); if (!TextUtils.isEmpty(lpp_prof)) { @@ -585,7 +580,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements /* * Overlay carrier properties from a debug configuration file. */ - loadPropertiesFromFile(properties); + loadPropertiesFromGpsDebugConfig(properties); // TODO: we should get rid of C2K specific setting. setSuplHostPort(properties.getProperty("SUPL_HOST"), properties.getProperty("SUPL_PORT")); @@ -655,25 +650,34 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } - private void loadPropertiesFromResource(Context context, - Properties properties) { - String[] configValues = context.getResources().getStringArray( - com.android.internal.R.array.config_gpsParameters); - for (String item : configValues) { - if (DEBUG) Log.d(TAG, "GpsParamsResource: " + item); - // We need to support "KEY =", but not "=VALUE". - int index = item.indexOf("="); - if (index > 0 && index + 1 < item.length()) { - String key = item.substring(0, index); - String value = item.substring(index + 1); - properties.setProperty(key.trim().toUpperCase(), value); - } else { - Log.w(TAG, "malformed contents: " + item); + private void loadPropertiesFromCarrierConfig(Context context, Properties properties) { + CarrierConfigManager configManager = (CarrierConfigManager) + mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (configManager == null) { + return; + } + PersistableBundle configs = configManager.getConfigForSubId( + SubscriptionManager.getDefaultDataSubscriptionId()); + if (configs == null) { + if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config."); + configs = CarrierConfigManager.getDefaultConfig(); + } + for (String configKey : configs.keySet()) { + if (configKey.startsWith(CarrierConfigManager.Gps.KEY_PREFIX)) { + String key = configKey + .substring(CarrierConfigManager.Gps.KEY_PREFIX.length()) + .toUpperCase(); + Object value = configs.get(configKey); + if (value instanceof String) { + // All GPS properties are of String type; convert so. + if (DEBUG) Log.d(TAG, "Gps config: " + key + " = " + value); + properties.setProperty(key, (String) value); + } } } } - private void loadPropertiesFromFile(Properties properties) { + private void loadPropertiesFromGpsDebugConfig(Properties properties) { try { File file = new File(DEBUG_PROPERTIES_FILE); FileInputStream stream = null; @@ -973,7 +977,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if (mSuplServerHost != null && mSuplServerPort > TCP_MIN_PORT && mSuplServerPort <= TCP_MAX_PORT) { - native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); + native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL, + mSuplServerHost, mSuplServerPort); } } @@ -1025,10 +1030,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // TODO: remove the following native calls if we can make sure they are redundant. if (mSuplServerHost != null) { - native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); + native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL, + mSuplServerHost, mSuplServerPort); } if (mC2KServerHost != null) { - native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); + native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K, + mC2KServerHost, mC2KServerPort); } mGnssMeasurementsProvider.onGpsEnabledChanged(); @@ -1575,8 +1582,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } @NativeEntryPoint - private void reportAGpsStatus(int type, int status, byte[] ipaddr) { - mNetworkConnectivityHandler.onReportAGpsStatus(type, status, ipaddr); + private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) { + mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr); } @NativeEntryPoint @@ -2018,8 +2025,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements case UPDATE_LOCATION: handleUpdateLocation((Location) msg.obj); break; - case SUBSCRIPTION_OR_SIM_CHANGED: - subscriptionOrSimChanged(mContext); + case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED: + subscriptionOrCarrierConfigChanged(mContext); break; case INITIALIZE_HANDLER: handleInitialize(); @@ -2086,7 +2093,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); intentFilter.addAction(Intent.ACTION_SCREEN_ON); - intentFilter.addAction(SIM_STATE_CHANGED); + intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this); mNetworkConnectivityHandler.registerNetworkCallbacks(); @@ -2168,8 +2175,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements return "DOWNLOAD_XTRA_DATA_FINISHED"; case UPDATE_LOCATION: return "UPDATE_LOCATION"; - case SUBSCRIPTION_OR_SIM_CHANGED: - return "SUBSCRIPTION_OR_SIM_CHANGED"; + case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED: + return "SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED"; case INITIALIZE_HANDLER: return "INITIALIZE_HANDLER"; case REPORT_LOCATION: diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java index 3903f2a69547..c38373ffc52a 100644 --- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java +++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java @@ -68,6 +68,12 @@ class GnssNetworkConnectivityHandler { private static final int AGNSS_NET_CAPABILITY_NOT_METERED = 1 << 0; private static final int AGNSS_NET_CAPABILITY_NOT_ROAMING = 1 << 1; + // these need to match AGnssType enum in IAGnssCallback.hal + public static final int AGPS_TYPE_SUPL = 1; + public static final int AGPS_TYPE_C2K = 2; + private static final int AGPS_TYPE_EIMS = 3; + private static final int AGPS_TYPE_IMS = 4; + // Default time limit in milliseconds for the ConnectivityManager to find a suitable // network with SUPL connectivity or report an error. private static final int SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS = 10 * 1000; @@ -86,6 +92,7 @@ class GnssNetworkConnectivityHandler { private int mAGpsDataConnectionState; private InetAddress mAGpsDataConnectionIpAddr; + private int mAGpsType; private final Context mContext; @@ -198,21 +205,11 @@ class GnssNetworkConnectivityHandler { /** * called from native code to update AGPS status */ - public void onReportAGpsStatus(int type, int status, byte[] ipaddr) { - switch (status) { + public void onReportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) { + switch (agpsStatus) { case GPS_REQUEST_AGPS_DATA_CONN: if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN"); - Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(ipaddr)); - InetAddress connectionIpAddress = null; - if (ipaddr != null) { - try { - connectionIpAddress = InetAddress.getByAddress(ipaddr); - if (DEBUG) Log.d(TAG, "IP address converted to: " + connectionIpAddress); - } catch (UnknownHostException e) { - Log.e(TAG, "Bad IP Address: " + ipaddr, e); - } - } - requestSuplConnection(connectionIpAddress); + requestSuplConnection(agpsType, suplIpAddr); break; case GPS_RELEASE_AGPS_DATA_CONN: if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN"); @@ -228,7 +225,7 @@ class GnssNetworkConnectivityHandler { if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); break; default: - if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + status); + if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + agpsStatus); } } @@ -308,8 +305,8 @@ class GnssNetworkConnectivityHandler { }; } - private void requestSuplConnection(InetAddress inetAddress) { - postEvent(() -> handleRequestSuplConnection(inetAddress)); + private void requestSuplConnection(int agpsType, byte[] suplIpAddr) { + postEvent(() -> handleRequestSuplConnection(agpsType, suplIpAddr)); } private void suplConnectionAvailable(Network network) { @@ -435,8 +432,15 @@ class GnssNetworkConnectivityHandler { // exception in the following call to native_agps_data_conn_open apn = "dummy-apn"; } + + // Setting route to host is needed for GNSS HAL implementations earlier than + // @2.0::IAgnssCallback. The HAL @2.0::IAgnssCallback.agnssStatusCb() method does + // not require setting route to SUPL host and hence does not provide an IP address. + if (mAGpsDataConnectionIpAddr != null) { + setRouting(); + } + int apnIpType = getApnIpType(apn); - setRouting(); if (DEBUG) { String message = String.format( "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s", @@ -444,29 +448,40 @@ class GnssNetworkConnectivityHandler { apnIpType); Log.d(TAG, message); } - native_agps_data_conn_open(apn, apnIpType); + native_agps_data_conn_open(network.getNetworkHandle(), apn, apnIpType); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; } } - private void handleRequestSuplConnection(InetAddress address) { + private void handleRequestSuplConnection(int agpsType, byte[] suplIpAddr) { + mAGpsDataConnectionIpAddr = null; + mAGpsType = agpsType; + if (suplIpAddr != null) { + if (VERBOSE) Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(suplIpAddr)); + try { + mAGpsDataConnectionIpAddr = InetAddress.getByAddress(suplIpAddr); + if (DEBUG) Log.d(TAG, "IP address converted to: " + mAGpsDataConnectionIpAddr); + } catch (UnknownHostException e) { + Log.e(TAG, "Bad IP Address: " + suplIpAddr, e); + } + } + if (DEBUG) { String message = String.format( - "requestSuplConnection, state=%s, address=%s", + "requestSuplConnection, state=%s, agpsType=%s, address=%s", agpsDataConnStateAsString(), - address); + agpsTypeAsString(agpsType), + mAGpsDataConnectionIpAddr); Log.d(TAG, message); } if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { return; } - mAGpsDataConnectionIpAddr = address; mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder(); - requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); - requestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL); + requestBuilder.addCapability(getNetworkCapability(mAGpsType)); NetworkRequest request = requestBuilder.build(); mConnMgr.requestNetwork( request, @@ -474,6 +489,20 @@ class GnssNetworkConnectivityHandler { SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS); } + private int getNetworkCapability(int agpsType) { + switch (agpsType) { + case AGPS_TYPE_C2K: + case AGPS_TYPE_SUPL: + return NetworkCapabilities.NET_CAPABILITY_SUPL; + case AGPS_TYPE_EIMS: + return NetworkCapabilities.NET_CAPABILITY_EIMS; + case AGPS_TYPE_IMS: + return NetworkCapabilities.NET_CAPABILITY_IMS; + default: + throw new IllegalArgumentException("agpsType: " + agpsType); + } + } + private void handleReleaseSuplConnection(int agpsDataConnStatus) { if (DEBUG) { String message = String.format( @@ -486,8 +515,8 @@ class GnssNetworkConnectivityHandler { if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_CLOSED) { return; } - mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; + mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; mConnMgr.unregisterNetworkCallback(mSuplConnectivityCallback); switch (agpsDataConnStatus) { case GPS_AGPS_DATA_CONN_FAILED: @@ -501,12 +530,9 @@ class GnssNetworkConnectivityHandler { } } + // TODO(25876485): Delete this method when all devices upgrade to HAL @2.0::IAGnssCallback + // interface which does not require setting route to host. private void setRouting() { - if (mAGpsDataConnectionIpAddr == null) { - return; - } - - // TODO(25876485): replace the use of this deprecated API boolean result = mConnMgr.requestRouteToHostAddress( ConnectivityManager.TYPE_MOBILE_SUPL, mAGpsDataConnectionIpAddr); @@ -564,6 +590,21 @@ class GnssNetworkConnectivityHandler { } } + private String agpsTypeAsString(int agpsType) { + switch (agpsType) { + case AGPS_TYPE_SUPL: + return "SUPL"; + case AGPS_TYPE_C2K: + return "C2K"; + case AGPS_TYPE_EIMS: + return "EIMS"; + case AGPS_TYPE_IMS: + return "IMS"; + default: + return "<Unknown>"; + } + } + private int getApnIpType(String apn) { ensureInHandlerThread(); if (apn == null) { @@ -614,7 +655,7 @@ class GnssNetworkConnectivityHandler { } // AGPS support - private native void native_agps_data_conn_open(String apn, int apnIpType); + private native void native_agps_data_conn_open(long networkHandle, String apn, int apnIpType); private native void native_agps_data_conn_closed(); diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index c1f3468627cb..dd2abde10433 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -19,7 +19,6 @@ package com.android.server.media; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManagerInternal; @@ -27,15 +26,16 @@ import android.media.AudioSystem; import android.media.MediaMetadata; 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.ISessionControllerCallback; 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.ParcelableVolumeInfo; import android.media.session.PlaybackState; +import android.media.session.SessionCallbackLink; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -45,7 +45,6 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; -import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemClock; import android.util.Log; @@ -56,6 +55,7 @@ import com.android.server.LocalServices; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; /** * This is the system implementation of a Session. Apps will interact with the @@ -85,7 +85,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private final Context mContext; private final Object mLock = new Object(); - private final ArrayList<ISessionControllerCallbackHolder> mControllerCallbackHolders = + private final ArrayList<ControllerCallbackLinkHolder> mControllerCallbackHolders = new ArrayList<>(); private long mFlags; @@ -98,7 +98,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { // may result in throwing an exception. private MediaMetadata mMetadata; private PlaybackState mPlaybackState; - private ParceledListSlice mQueue; + private List<QueueItem> mQueue; private CharSequence mQueueTitle; private int mRatingType; // End TransportPerformer fields @@ -121,7 +121,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private String mMetadataDescription; public MediaSessionRecord(int ownerPid, int ownerUid, int userId, String ownerPackageName, - ISessionCallback cb, String tag, MediaSessionService service, Looper handlerLooper) { + SessionCallbackLink cb, String tag, MediaSessionService service, Looper handlerLooper) { mOwnerPid = ownerPid; mOwnerUid = ownerUid; mUserId = userId; @@ -249,7 +249,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { * @param useSuggested True to use adjustSuggestedStreamVolume instead of */ public void adjustVolume(String packageName, int pid, int uid, - ISessionControllerCallback caller, boolean asSystemService, int direction, int flags, + ControllerCallbackLink caller, boolean asSystemService, int direction, int flags, boolean useSuggested) { int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND; if (isPlaybackActive() || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) { @@ -291,7 +291,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } private void setVolumeTo(String packageName, int pid, int uid, - ISessionControllerCallback caller, int value, int flags) { + ControllerCallbackLink caller, int value, int flags) { if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); mAudioManagerInternal.setStreamVolumeForUid(stream, value, flags, packageName, uid); @@ -428,7 +428,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } } - public ISessionCallback getCallback() { + public SessionCallbackLink getCallback() { return mSessionCb.mCb; } @@ -456,7 +456,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { + ", max=" + mMaxVolume + ", current=" + mCurrentVolume); pw.println(indent + "metadata: " + mMetadataDescription); pw.println(indent + "queueTitle=" + mQueueTitle + ", size=" - + (mQueue == null ? 0 : mQueue.getList().size())); + + (mQueue == null ? 0 : mQueue.size())); } @Override @@ -498,7 +498,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } private void logCallbackException( - String msg, ISessionControllerCallbackHolder holder, Exception e) { + String msg, ControllerCallbackLinkHolder holder, Exception e) { Log.v(TAG, msg + ", this=" + this + ", callback package=" + holder.mPackageName + ", exception=" + e); } @@ -509,16 +509,18 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onPlaybackStateChanged(mPlaybackState); - } catch (DeadObjectException e) { - mControllerCallbackHolders.remove(i); - logCallbackException("Removed dead callback in pushPlaybackStateUpdate", - holder, e); - } catch (RemoteException e) { - logCallbackException("unexpected exception in pushPlaybackStateUpdate", - holder, e); + holder.mCallback.notifyPlaybackStateChanged(mPlaybackState); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushPlaybackStateUpdate", + holder, e); + } else { + logCallbackException("unexpected exception in pushPlaybackStateUpdate", + holder, e); + } } } } @@ -530,14 +532,18 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onMetadataChanged(mMetadata); - } catch (DeadObjectException e) { - logCallbackException("Removing dead callback in pushMetadataUpdate", holder, e); - mControllerCallbackHolders.remove(i); - } catch (RemoteException e) { - logCallbackException("unexpected exception in pushMetadataUpdate", holder, e); + holder.mCallback.notifyMetadataChanged(mMetadata); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushMetadataUpdate", + holder, e); + } else { + logCallbackException("unexpected exception in pushMetadataUpdate", + holder, e); + } } } } @@ -549,14 +555,17 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onQueueChanged(mQueue); - } catch (DeadObjectException e) { - mControllerCallbackHolders.remove(i); - logCallbackException("Removed dead callback in pushQueueUpdate", holder, e); - } catch (RemoteException e) { - logCallbackException("unexpected exception in pushQueueUpdate", holder, e); + holder.mCallback.notifyQueueChanged(mQueue); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushQueueUpdate", + holder, e); + } else { + logCallbackException("unexpected exception in pushQueueUpdate", holder, e); + } } } } @@ -568,16 +577,18 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onQueueTitleChanged(mQueueTitle); - } catch (DeadObjectException e) { - mControllerCallbackHolders.remove(i); - logCallbackException("Removed dead callback in pushQueueTitleUpdate", - holder, e); - } catch (RemoteException e) { - logCallbackException("unexpected exception in pushQueueTitleUpdate", - holder, e); + holder.mCallback.notifyQueueTitleChanged(mQueueTitle); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushQueueTitleUpdate", + holder, e); + } else { + logCallbackException("unexpected exception in pushQueueTitleUpdate", + holder, e); + } } } } @@ -589,14 +600,17 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onExtrasChanged(mExtras); - } catch (DeadObjectException e) { - mControllerCallbackHolders.remove(i); - logCallbackException("Removed dead callback in pushExtrasUpdate", holder, e); - } catch (RemoteException e) { - logCallbackException("unexpected exception in pushExtrasUpdate", holder, e); + holder.mCallback.notifyExtrasChanged(mExtras); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushExtrasUpdate", + holder, e); + } else { + logCallbackException("unexpected exception in pushExtrasUpdate", holder, e); + } } } } @@ -609,14 +623,18 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } ParcelableVolumeInfo info = mController.getVolumeAttributes(); for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onVolumeInfoChanged(info); - } catch (DeadObjectException e) { - mControllerCallbackHolders.remove(i); - logCallbackException("Removing dead callback in pushVolumeUpdate", holder, e); - } catch (RemoteException e) { - logCallbackException("Unexpected exception in pushVolumeUpdate", holder, e); + holder.mCallback.notifyVolumeInfoChanged(info.volumeType, info.audioAttrs, + info.controlType, info.maxVolume, info.currentVolume); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushVolumeUpdate", + holder, e); + } else { + logCallbackException("unexpected exception in pushVolumeUpdate", holder, e); + } } } } @@ -628,14 +646,16 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onEvent(event, data); - } catch (DeadObjectException e) { - mControllerCallbackHolders.remove(i); - logCallbackException("Removing dead callback in pushEvent", holder, e); - } catch (RemoteException e) { - logCallbackException("unexpected exception in pushEvent", holder, e); + holder.mCallback.notifyEvent(event, data); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushEvent", holder, e); + } else { + logCallbackException("unexpected exception in pushEvent", holder, e); + } } } } @@ -649,14 +669,18 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i); + ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i); try { - holder.mCallback.onSessionDestroyed(); - } catch (DeadObjectException e) { - logCallbackException("Removing dead callback in pushEvent", holder, e); - mControllerCallbackHolders.remove(i); - } catch (RemoteException e) { - logCallbackException("unexpected exception in pushEvent", holder, e); + holder.mCallback.notifySessionDestroyed(); + } catch (RuntimeException e) { + if (e.getCause() instanceof DeadObjectException) { + mControllerCallbackHolders.remove(i); + logCallbackException("Removing dead callback in pushSessionDestroyed", + holder, e); + } else { + logCallbackException("unexpected exception in pushSessionDestroyed", + holder, e); + } } } // After notifying clear all listeners @@ -696,10 +720,10 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return result == null ? state : result; } - private int getControllerHolderIndexForCb(ISessionControllerCallback cb) { - IBinder binder = cb.asBinder(); + private int getControllerHolderIndexForCb(ControllerCallbackLink cb) { + IBinder binder = cb.getBinder(); for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) { - if (binder.equals(mControllerCallbackHolders.get(i).mCallback.asBinder())) { + if (binder.equals(mControllerCallbackHolders.get(i).mCallback.getBinder())) { return i; } } @@ -823,7 +847,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public void setQueue(ParceledListSlice queue) { + public void setQueue(List<QueueItem> queue) { synchronized (mLock) { mQueue = queue; } @@ -900,9 +924,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } class SessionCb { - private final ISessionCallback mCb; + private final SessionCallbackLink mCb; - public SessionCb(ISessionCallback cb) { + SessionCb(SessionCallbackLink cb) { mCb = cb; } @@ -910,224 +934,224 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { boolean asSystemService, KeyEvent keyEvent, int sequenceId, ResultReceiver cb) { try { if (asSystemService) { - mCb.onMediaButton(mContext.getPackageName(), Process.myPid(), + mCb.notifyMediaButton(mContext.getPackageName(), Process.myPid(), Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), sequenceId, cb); } else { - mCb.onMediaButton(packageName, pid, uid, + mCb.notifyMediaButton(packageName, pid, uid, createMediaButtonIntent(keyEvent), sequenceId, cb); } return true; - } catch (RemoteException e) { + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in sendMediaRequest.", e); } return false; } public boolean sendMediaButton(String packageName, int pid, int uid, - ISessionControllerCallback caller, boolean asSystemService, + ControllerCallbackLink caller, boolean asSystemService, KeyEvent keyEvent) { try { if (asSystemService) { - mCb.onMediaButton(mContext.getPackageName(), Process.myPid(), + mCb.notifyMediaButton(mContext.getPackageName(), Process.myPid(), Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), 0, null); } else { - mCb.onMediaButtonFromController(packageName, pid, uid, caller, + mCb.notifyMediaButtonFromController(packageName, pid, uid, caller, createMediaButtonIntent(keyEvent)); } return true; - } catch (RemoteException e) { + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in sendMediaRequest.", e); } return false; } public void sendCommand(String packageName, int pid, int uid, - ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) { + ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { try { - mCb.onCommand(packageName, pid, uid, caller, command, args, cb); - } catch (RemoteException e) { + mCb.notifyCommand(packageName, pid, uid, caller, command, args, cb); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in sendCommand.", e); } } public void sendCustomAction(String packageName, int pid, int uid, - ISessionControllerCallback caller, String action, + ControllerCallbackLink caller, String action, Bundle args) { try { - mCb.onCustomAction(packageName, pid, uid, caller, action, args); - } catch (RemoteException e) { + mCb.notifyCustomAction(packageName, pid, uid, caller, action, args); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in sendCustomAction.", e); } } public void prepare(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { try { - mCb.onPrepare(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyPrepare(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in prepare.", e); } } public void prepareFromMediaId(String packageName, int pid, int uid, - ISessionControllerCallback caller, String mediaId, Bundle extras) { + ControllerCallbackLink caller, String mediaId, Bundle extras) { try { - mCb.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras); - } catch (RemoteException e) { + mCb.notifyPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in prepareFromMediaId.", e); } } public void prepareFromSearch(String packageName, int pid, int uid, - ISessionControllerCallback caller, String query, Bundle extras) { + ControllerCallbackLink caller, String query, Bundle extras) { try { - mCb.onPrepareFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RemoteException e) { + mCb.notifyPrepareFromSearch(packageName, pid, uid, caller, query, extras); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in prepareFromSearch.", e); } } public void prepareFromUri(String packageName, int pid, int uid, - ISessionControllerCallback caller, Uri uri, Bundle extras) { + ControllerCallbackLink caller, Uri uri, Bundle extras) { try { - mCb.onPrepareFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RemoteException e) { + mCb.notifyPrepareFromUri(packageName, pid, uid, caller, uri, extras); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in prepareFromUri.", e); } } - public void play(String packageName, int pid, int uid, ISessionControllerCallback caller) { + public void play(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.onPlay(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyPlay(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in play.", e); } } public void playFromMediaId(String packageName, int pid, int uid, - ISessionControllerCallback caller, String mediaId, Bundle extras) { + ControllerCallbackLink caller, String mediaId, Bundle extras) { try { - mCb.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); - } catch (RemoteException e) { + mCb.notifyPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in playFromMediaId.", e); } } public void playFromSearch(String packageName, int pid, int uid, - ISessionControllerCallback caller, String query, Bundle extras) { + ControllerCallbackLink caller, String query, Bundle extras) { try { - mCb.onPlayFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RemoteException e) { + mCb.notifyPlayFromSearch(packageName, pid, uid, caller, query, extras); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in playFromSearch.", e); } } public void playFromUri(String packageName, int pid, int uid, - ISessionControllerCallback caller, Uri uri, Bundle extras) { + ControllerCallbackLink caller, Uri uri, Bundle extras) { try { - mCb.onPlayFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RemoteException e) { + mCb.notifyPlayFromUri(packageName, pid, uid, caller, uri, extras); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in playFromUri.", e); } } public void skipToTrack(String packageName, int pid, int uid, - ISessionControllerCallback caller, long id) { + ControllerCallbackLink caller, long id) { try { - mCb.onSkipToTrack(packageName, pid, uid, caller, id); - } catch (RemoteException e) { + mCb.notifySkipToTrack(packageName, pid, uid, caller, id); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in skipToTrack", e); } } - public void pause(String packageName, int pid, int uid, ISessionControllerCallback caller) { + public void pause(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.onPause(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyPause(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in pause.", e); } } - public void stop(String packageName, int pid, int uid, ISessionControllerCallback caller) { + public void stop(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.onStop(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyStop(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in stop.", e); } } - public void next(String packageName, int pid, int uid, ISessionControllerCallback caller) { + public void next(String packageName, int pid, int uid, ControllerCallbackLink caller) { try { - mCb.onNext(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyNext(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in next.", e); } } public void previous(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { try { - mCb.onPrevious(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyPrevious(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in previous.", e); } } public void fastForward(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { try { - mCb.onFastForward(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyFastForward(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in fastForward.", e); } } public void rewind(String packageName, int pid, int uid, - ISessionControllerCallback caller) { + ControllerCallbackLink caller) { try { - mCb.onRewind(packageName, pid, uid, caller); - } catch (RemoteException e) { + mCb.notifyRewind(packageName, pid, uid, caller); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in rewind.", e); } } - public void seekTo(String packageName, int pid, int uid, ISessionControllerCallback caller, + public void seekTo(String packageName, int pid, int uid, ControllerCallbackLink caller, long pos) { try { - mCb.onSeekTo(packageName, pid, uid, caller, pos); - } catch (RemoteException e) { + mCb.notifySeekTo(packageName, pid, uid, caller, pos); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in seekTo.", e); } } - public void rate(String packageName, int pid, int uid, ISessionControllerCallback caller, + public void rate(String packageName, int pid, int uid, ControllerCallbackLink caller, Rating rating) { try { - mCb.onRate(packageName, pid, uid, caller, rating); - } catch (RemoteException e) { + mCb.notifyRate(packageName, pid, uid, caller, rating); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in rate.", e); } } public void adjustVolume(String packageName, int pid, int uid, - ISessionControllerCallback caller, boolean asSystemService, int direction) { + ControllerCallbackLink caller, boolean asSystemService, int direction) { try { if (asSystemService) { - mCb.onAdjustVolume(mContext.getPackageName(), Process.myPid(), + mCb.notifyAdjustVolume(mContext.getPackageName(), Process.myPid(), Process.SYSTEM_UID, null, direction); } else { - mCb.onAdjustVolume(packageName, pid, uid, caller, direction); + mCb.notifyAdjustVolume(packageName, pid, uid, caller, direction); } - } catch (RemoteException e) { + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in adjustVolume.", e); } } public void setVolumeTo(String packageName, int pid, int uid, - ISessionControllerCallback caller, int value) { + ControllerCallbackLink caller, int value) { try { - mCb.onSetVolumeTo(packageName, pid, uid, caller, value); - } catch (RemoteException e) { + mCb.notifySetVolumeTo(packageName, pid, uid, caller, value); + } catch (RuntimeException e) { Slog.e(TAG, "Remote failure in setVolumeTo.", e); } } @@ -1141,34 +1165,34 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { class ControllerStub extends ISessionController.Stub { @Override - public void sendCommand(String packageName, ISessionControllerCallback caller, + public void sendCommand(String packageName, ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { mSessionCb.sendCommand(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, command, args, cb); } @Override - public boolean sendMediaButton(String packageName, ISessionControllerCallback cb, + public boolean sendMediaButton(String packageName, ControllerCallbackLink cb, boolean asSystemService, KeyEvent keyEvent) { return mSessionCb.sendMediaButton(packageName, Binder.getCallingPid(), Binder.getCallingUid(), cb, asSystemService, keyEvent); } @Override - public void registerCallbackListener(String packageName, ISessionControllerCallback cb) { + public void registerCallbackListener(String packageName, ControllerCallbackLink cb) { synchronized (mLock) { // If this session is already destroyed tell the caller and // don't add them. if (mDestroyed) { try { - cb.onSessionDestroyed(); + cb.notifySessionDestroyed(); } catch (Exception e) { // ignored } return; } if (getControllerHolderIndexForCb(cb) < 0) { - mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb, + mControllerCallbackHolders.add(new ControllerCallbackLinkHolder(cb, packageName, Binder.getCallingUid())); if (DEBUG) { Log.d(TAG, "registering controller callback " + cb + " from controller" @@ -1179,14 +1203,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public void unregisterCallbackListener(ISessionControllerCallback cb) { + public void unregisterCallbackListener(ControllerCallbackLink cb) { synchronized (mLock) { int index = getControllerHolderIndexForCb(cb); if (index != -1) { mControllerCallbackHolders.remove(index); } if (DEBUG) { - Log.d(TAG, "unregistering callback " + cb.asBinder()); + Log.d(TAG, "unregistering callback " + cb.getBinder()); } } } @@ -1232,7 +1256,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public void adjustVolume(String packageName, ISessionControllerCallback caller, + public void adjustVolume(String packageName, ControllerCallbackLink caller, boolean asSystemService, int direction, int flags) { int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); @@ -1246,7 +1270,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public void setVolumeTo(String packageName, ISessionControllerCallback caller, + public void setVolumeTo(String packageName, ControllerCallbackLink caller, int value, int flags) { int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); @@ -1259,110 +1283,110 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public void prepare(String packageName, ISessionControllerCallback caller) { + public void prepare(String packageName, ControllerCallbackLink caller) { mSessionCb.prepare(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void prepareFromMediaId(String packageName, ISessionControllerCallback caller, + public void prepareFromMediaId(String packageName, ControllerCallbackLink caller, String mediaId, Bundle extras) { mSessionCb.prepareFromMediaId(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, mediaId, extras); } @Override - public void prepareFromSearch(String packageName, ISessionControllerCallback caller, + public void prepareFromSearch(String packageName, ControllerCallbackLink caller, String query, Bundle extras) { mSessionCb.prepareFromSearch(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, query, extras); } @Override - public void prepareFromUri(String packageName, ISessionControllerCallback caller, + public void prepareFromUri(String packageName, ControllerCallbackLink caller, Uri uri, Bundle extras) { mSessionCb.prepareFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, uri, extras); } @Override - public void play(String packageName, ISessionControllerCallback caller) { + public void play(String packageName, ControllerCallbackLink caller) { mSessionCb.play(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void playFromMediaId(String packageName, ISessionControllerCallback caller, + public void playFromMediaId(String packageName, ControllerCallbackLink caller, String mediaId, Bundle extras) { mSessionCb.playFromMediaId(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, mediaId, extras); } @Override - public void playFromSearch(String packageName, ISessionControllerCallback caller, + public void playFromSearch(String packageName, ControllerCallbackLink caller, String query, Bundle extras) { mSessionCb.playFromSearch(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, query, extras); } @Override - public void playFromUri(String packageName, ISessionControllerCallback caller, + public void playFromUri(String packageName, ControllerCallbackLink caller, Uri uri, Bundle extras) { mSessionCb.playFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, uri, extras); } @Override - public void skipToQueueItem(String packageName, ISessionControllerCallback caller, + public void skipToQueueItem(String packageName, ControllerCallbackLink caller, long id) { mSessionCb.skipToTrack(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, id); } @Override - public void pause(String packageName, ISessionControllerCallback caller) { + public void pause(String packageName, ControllerCallbackLink caller) { mSessionCb.pause(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void stop(String packageName, ISessionControllerCallback caller) { + public void stop(String packageName, ControllerCallbackLink caller) { mSessionCb.stop(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void next(String packageName, ISessionControllerCallback caller) { + public void next(String packageName, ControllerCallbackLink caller) { mSessionCb.next(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void previous(String packageName, ISessionControllerCallback caller) { + public void previous(String packageName, ControllerCallbackLink caller) { mSessionCb.previous(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void fastForward(String packageName, ISessionControllerCallback caller) { + public void fastForward(String packageName, ControllerCallbackLink caller) { mSessionCb.fastForward(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void rewind(String packageName, ISessionControllerCallback caller) { + public void rewind(String packageName, ControllerCallbackLink caller) { mSessionCb.rewind(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller); } @Override - public void seekTo(String packageName, ISessionControllerCallback caller, long pos) { + public void seekTo(String packageName, ControllerCallbackLink caller, long pos) { mSessionCb.seekTo(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, pos); } @Override - public void rate(String packageName, ISessionControllerCallback caller, Rating rating) { + public void rate(String packageName, ControllerCallbackLink caller, Rating rating) { mSessionCb.rate(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, rating); } @Override - public void sendCustomAction(String packageName, ISessionControllerCallback caller, + public void sendCustomAction(String packageName, ControllerCallbackLink caller, String action, Bundle args) { mSessionCb.sendCustomAction(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller, action, args); @@ -1381,7 +1405,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public ParceledListSlice getQueue() { + public List<QueueItem> getQueue() { synchronized (mLock) { return mQueue; } @@ -1410,12 +1434,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } } - private class ISessionControllerCallbackHolder { - private final ISessionControllerCallback mCallback; + private class ControllerCallbackLinkHolder { + private final ControllerCallbackLink mCallback; private final String mPackageName; private final int mUid; - ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName, + ControllerCallbackLinkHolder(ControllerCallbackLink callback, String packageName, int uid) { mCallback = callback; mPackageName = packageName; diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 93b66208e752..b807c47c09b9 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -16,6 +16,7 @@ package com.android.server.media; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.INotificationManager; import android.app.KeyguardManager; @@ -27,8 +28,10 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.media.AudioManager; @@ -41,10 +44,10 @@ 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.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; @@ -404,7 +407,7 @@ public class MediaSessionService extends SystemService implements Monitor { } try { - session.getCallback().asBinder().unlinkToDeath(session, 0); + session.getCallback().getBinder().unlinkToDeath(session, 0); } catch (Exception e) { // ignore exceptions while destroying a session. } @@ -490,7 +493,7 @@ public class MediaSessionService extends SystemService implements Monitor { } private MediaSessionRecord createSessionInternal(int callerPid, int callerUid, int userId, - String callerPackageName, ISessionCallback cb, String tag) throws RemoteException { + String callerPackageName, SessionCallbackLink cb, String tag) throws RemoteException { synchronized (mLock) { return createSessionLocked(callerPid, callerUid, userId, callerPackageName, cb, tag); } @@ -504,7 +507,7 @@ public class MediaSessionService extends SystemService implements Monitor { * 4. It needs to be added to the relevant user record. */ private MediaSessionRecord createSessionLocked(int callerPid, int callerUid, int userId, - String callerPackageName, ISessionCallback cb, String tag) { + String callerPackageName, SessionCallbackLink cb, String tag) { FullUserRecord user = getFullUserRecordLocked(userId); if (user == null) { Log.wtf(TAG, "Request from invalid user: " + userId); @@ -514,7 +517,7 @@ public class MediaSessionService extends SystemService implements Monitor { final MediaSessionRecord session = new MediaSessionRecord(callerPid, callerUid, userId, callerPackageName, cb, tag, this, mHandler.getLooper()); try { - cb.asBinder().linkToDeath(session, 0); + cb.getBinder().linkToDeath(session, 0); } catch (RemoteException e) { throw new RuntimeException("Media Session owner died prematurely.", e); } @@ -634,11 +637,17 @@ public class MediaSessionService extends SystemService implements Monitor { * <p>The contents of this object is guarded by {@link #mLock}. */ final class FullUserRecord implements MediaSessionStack.OnMediaButtonSessionChangedListener { + public static final int COMPONENT_TYPE_INVALID = 0; + public static final int COMPONENT_TYPE_BROADCAST = 1; + public static final int COMPONENT_TYPE_ACTIVITY = 2; + public static final int COMPONENT_TYPE_SERVICE = 3; private static final String COMPONENT_NAME_USER_ID_DELIM = ","; + private final int mFullUserId; private final MediaSessionStack mPriorityStack; private PendingIntent mLastMediaButtonReceiver; private ComponentName mRestoredMediaButtonReceiver; + private int mRestoredMediaButtonReceiverComponentType; private int mRestoredMediaButtonReceiverUserId; private IOnVolumeKeyLongPressListener mOnVolumeKeyLongPressListener; @@ -655,17 +664,23 @@ public class MediaSessionService extends SystemService implements Monitor { mFullUserId = fullUserId; mPriorityStack = new MediaSessionStack(mAudioPlayerStateMonitor, this); // Restore the remembered media button receiver before the boot. - String mediaButtonReceiver = Settings.Secure.getStringForUser(mContentResolver, + String mediaButtonReceiverInfo = Settings.Secure.getStringForUser(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER, mFullUserId); - if (mediaButtonReceiver == null) { + if (mediaButtonReceiverInfo == null) { return; } - String[] tokens = mediaButtonReceiver.split(COMPONENT_NAME_USER_ID_DELIM); - if (tokens == null || tokens.length != 2) { + String[] tokens = mediaButtonReceiverInfo.split(COMPONENT_NAME_USER_ID_DELIM); + if (tokens == null || (tokens.length != 2 && tokens.length != 3)) { return; } mRestoredMediaButtonReceiver = ComponentName.unflattenFromString(tokens[0]); mRestoredMediaButtonReceiverUserId = Integer.parseInt(tokens[1]); + if (tokens.length == 3) { + mRestoredMediaButtonReceiverComponentType = Integer.parseInt(tokens[2]); + } else { + mRestoredMediaButtonReceiverComponentType = + getComponentType(mRestoredMediaButtonReceiver); + } } public void destroySessionsForUserLocked(int userId) { @@ -696,6 +711,8 @@ public class MediaSessionService extends SystemService implements Monitor { pw.println(indent + "Callback: " + mCallback); pw.println(indent + "Last MediaButtonReceiver: " + mLastMediaButtonReceiver); pw.println(indent + "Restored MediaButtonReceiver: " + mRestoredMediaButtonReceiver); + pw.println(indent + "Restored MediaButtonReceiverComponentType: " + + mRestoredMediaButtonReceiverComponentType); mPriorityStack.dump(pw, indent); } @@ -722,17 +739,22 @@ public class MediaSessionService extends SystemService implements Monitor { PendingIntent receiver = record.getMediaButtonReceiver(); mLastMediaButtonReceiver = receiver; mRestoredMediaButtonReceiver = null; - String componentName = ""; + mRestoredMediaButtonReceiverComponentType = COMPONENT_TYPE_INVALID; + + String mediaButtonReceiverInfo = ""; if (receiver != null) { ComponentName component = receiver.getIntent().getComponent(); if (component != null && record.getPackageName().equals(component.getPackageName())) { - componentName = component.flattenToString(); + String componentName = component.flattenToString(); + int componentType = getComponentType(component); + mediaButtonReceiverInfo = String.join(COMPONENT_NAME_USER_ID_DELIM, + componentName, String.valueOf(record.getUserId()), + String.valueOf(componentType)); } } Settings.Secure.putStringForUser(mContentResolver, - Settings.System.MEDIA_BUTTON_RECEIVER, - componentName + COMPONENT_NAME_USER_ID_DELIM + record.getUserId(), + Settings.System.MEDIA_BUTTON_RECEIVER, mediaButtonReceiverInfo, mFullUserId); } @@ -762,6 +784,35 @@ public class MediaSessionService extends SystemService implements Monitor { return isGlobalPriorityActiveLocked() ? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession(); } + + private int getComponentType(@Nullable ComponentName componentName) { + if (componentName == null) { + return COMPONENT_TYPE_INVALID; + } + PackageManager pm = getContext().getPackageManager(); + try { + ActivityInfo activityInfo = pm.getActivityInfo(componentName, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.GET_ACTIVITIES); + if (activityInfo != null) { + return COMPONENT_TYPE_ACTIVITY; + } + } catch (NameNotFoundException e) { + } + try { + ServiceInfo serviceInfo = pm.getServiceInfo(componentName, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.GET_SERVICES); + if (serviceInfo != null) { + return COMPONENT_TYPE_SERVICE; + } + } catch (NameNotFoundException e) { + } + // Pick legacy behavior for BroadcastReceiver or unknown. + return COMPONENT_TYPE_BROADCAST; + } } final class SessionsListenerRecord implements IBinder.DeathRecipient { @@ -817,7 +868,7 @@ public class MediaSessionService extends SystemService implements Monitor { private boolean mVoiceButtonHandled = false; @Override - public ISession createSession(String packageName, ISessionCallback cb, String tag, + public ISession createSession(String packageName, SessionCallbackLink cb, String tag, int userId) throws RemoteException { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); @@ -1580,14 +1631,32 @@ public class MediaSessionService extends SystemService implements Monitor { } else { ComponentName receiver = mCurrentFullUserRecord.mRestoredMediaButtonReceiver; + int componentType = mCurrentFullUserRecord + .mRestoredMediaButtonReceiverComponentType; + UserHandle userHandle = UserHandle.of(mCurrentFullUserRecord + .mRestoredMediaButtonReceiverUserId); if (DEBUG_KEY_EVENT) { Log.d(TAG, "Sending " + keyEvent + " to the restored intent " - + receiver); + + receiver + ", type=" + componentType); } mediaButtonIntent.setComponent(receiver); - getContext().sendBroadcastAsUser(mediaButtonIntent, - UserHandle.of(mCurrentFullUserRecord - .mRestoredMediaButtonReceiverUserId)); + try { + switch (componentType) { + case FullUserRecord.COMPONENT_TYPE_ACTIVITY: + getContext().startActivityAsUser(mediaButtonIntent, userHandle); + break; + case FullUserRecord.COMPONENT_TYPE_SERVICE: + getContext().startForegroundServiceAsUser(mediaButtonIntent, + userHandle); + break; + default: + // Legacy behavior for other cases. + getContext().sendBroadcastAsUser(mediaButtonIntent, userHandle); + } + } catch (Exception e) { + Log.w(TAG, "Error sending media button to the restored intent " + + receiver + ", type=" + componentType, e); + } if (mCurrentFullUserRecord.mCallback != null) { mCurrentFullUserRecord.mCallback .onMediaKeyEventDispatchedToMediaButtonReceiver( diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index d50fdfa9f61e..85a8d938d693 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -144,7 +144,6 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.ShellCallback; -import android.os.ShellCommand; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; @@ -3852,7 +3851,8 @@ public class NotificationManagerService extends SystemService { public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException { - new ShellCmd().exec(this, in, out, err, args, callback, resultReceiver); + new NotificationShellCmd(NotificationManagerService.this) + .exec(this, in, out, err, args, callback, resultReceiver); } }; @@ -7727,110 +7727,6 @@ public class NotificationManagerService extends SystemService { } } - private class ShellCmd extends ShellCommand { - public static final String USAGE = "help\n" - + "allow_listener COMPONENT [user_id]\n" - + "disallow_listener COMPONENT [user_id]\n" - + "allow_assistant COMPONENT\n" - + "remove_assistant COMPONENT\n" - + "allow_dnd PACKAGE\n" - + "disallow_dnd PACKAGE\n" - + "suspend_package PACKAGE\n" - + "unsuspend_package PACKAGE"; - - @Override - public int onCommand(String cmd) { - if (cmd == null) { - return handleDefaultCommands(cmd); - } - final PrintWriter pw = getOutPrintWriter(); - try { - switch (cmd) { - case "allow_dnd": { - getBinderService().setNotificationPolicyAccessGranted( - getNextArgRequired(), true); - } - break; - - case "disallow_dnd": { - getBinderService().setNotificationPolicyAccessGranted( - getNextArgRequired(), false); - } - break; - case "allow_listener": { - ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); - if (cn == null) { - pw.println("Invalid listener - must be a ComponentName"); - return -1; - } - String userId = getNextArg(); - if (userId == null) { - getBinderService().setNotificationListenerAccessGranted(cn, true); - } else { - getBinderService().setNotificationListenerAccessGrantedForUser( - cn, Integer.parseInt(userId), true); - } - } - break; - case "disallow_listener": { - ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); - if (cn == null) { - pw.println("Invalid listener - must be a ComponentName"); - return -1; - } - String userId = getNextArg(); - if (userId == null) { - getBinderService().setNotificationListenerAccessGranted(cn, false); - } else { - getBinderService().setNotificationListenerAccessGrantedForUser( - cn, Integer.parseInt(userId), false); - } - } - break; - case "allow_assistant": { - ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); - if (cn == null) { - pw.println("Invalid assistant - must be a ComponentName"); - return -1; - } - getBinderService().setNotificationAssistantAccessGranted(cn, true); - } - break; - case "disallow_assistant": { - ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); - if (cn == null) { - pw.println("Invalid assistant - must be a ComponentName"); - return -1; - } - getBinderService().setNotificationAssistantAccessGranted(cn, false); - } - break; - case "suspend_package": { - // only use for testing - simulatePackageSuspendBroadcast(true, getNextArgRequired()); - } - break; - case "unsuspend_package": { - // only use for testing - simulatePackageSuspendBroadcast(false, getNextArgRequired()); - } - break; - default: - return handleDefaultCommands(cmd); - } - } catch (Exception e) { - pw.println("Error occurred. Check logcat for details. " + e.getMessage()); - Slog.e(TAG, "Error running shell command", e); - } - return 0; - } - - @Override - public void onHelp() { - getOutPrintWriter().println(USAGE); - } - } - private void writeSecureNotificationsPolicy(XmlSerializer out) throws IOException { out.startTag(null, LOCKSCREEN_ALLOW_SECURE_NOTIFICATIONS_TAG); out.attribute(null, LOCKSCREEN_ALLOW_SECURE_NOTIFICATIONS_VALUE, diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java new file mode 100644 index 000000000000..3d88f20f0710 --- /dev/null +++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java @@ -0,0 +1,483 @@ +/* + * 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.server.notification; + +import android.app.INotificationManager; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Person; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ParceledListSlice; +import android.content.res.Resources; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; +import android.net.Uri; +import android.os.Binder; +import android.os.RemoteException; +import android.os.ShellCommand; +import android.os.UserHandle; +import android.text.TextUtils; +import android.util.Slog; + +import java.io.PrintWriter; +import java.net.URISyntaxException; +import java.util.Collections; + +/** + * Implementation of `cmd notification` in NotificationManagerService. + */ +public class NotificationShellCmd extends ShellCommand { + private static final String USAGE = + "usage: cmd notification SUBCMD [args]\n\n" + + "SUBCMDs:\n" + + " allow_listener COMPONENT [user_id]\n" + + " disallow_listener COMPONENT [user_id]\n" + + " allow_assistant COMPONENT\n" + + " remove_assistant COMPONENT\n" + + " allow_dnd PACKAGE\n" + + " disallow_dnd PACKAGE\n" + + " suspend_package PACKAGE\n" + + " unsuspend_package PACKAGE\n" + + " post [--help | flags] TAG TEXT"; + + private static final String NOTIFY_USAGE = + "usage: cmd notification post [flags] <tag> <text>\n\n" + + "flags:\n" + + " -h|--help\n" + + " -v|--verbose\n" + + " -t|--title <text>\n" + + " -i|--icon <iconspec>\n" + + " -I|--large-icon <iconspec>\n" + + " -S|--style <style> [styleargs]\n" + + " -c|--content-intent <intentspec>\n" + + "\n" + + "styles: (default none)\n" + + " bigtext\n" + + " bigpicture --picture <iconspec>\n" + + " inbox --line <text> --line <text> ...\n" + + " messaging --conversation <title> --message <who>:<text> ...\n" + + " media\n" + + "\n" + + "an <iconspec> is one of\n" + + " file:///data/local/tmp/<img.png>\n" + + " content://<provider>/<path>\n" + + " @[<package>:]drawable/<img>\n" + + " data:base64,<B64DATA==>\n" + + "\n" + + "an <intentspec> is (broadcast|service|activity) <args>\n" + + " <args> are as described in `am start`"; + + public static final int NOTIFICATION_ID = 1138; + public static final String NOTIFICATION_PACKAGE = "com.android.shell"; + public static final String CHANNEL_ID = "shellcmd"; + public static final String CHANNEL_NAME = "Shell command"; + public static final int CHANNEL_IMP = NotificationManager.IMPORTANCE_DEFAULT; + + private final NotificationManagerService mDirectService; + private final INotificationManager mBinderService; + + public NotificationShellCmd(NotificationManagerService service) { + mDirectService = service; + mBinderService = service.getBinderService(); + } + + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(cmd); + } + final PrintWriter pw = getOutPrintWriter(); + try { + switch (cmd.replace('-', '_')) { + case "allow_dnd": { + mBinderService.setNotificationPolicyAccessGranted( + getNextArgRequired(), true); + } + break; + + case "disallow_dnd": { + mBinderService.setNotificationPolicyAccessGranted( + getNextArgRequired(), false); + } + break; + case "allow_listener": { + ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); + if (cn == null) { + pw.println("Invalid listener - must be a ComponentName"); + return -1; + } + String userId = getNextArg(); + if (userId == null) { + mBinderService.setNotificationListenerAccessGranted(cn, true); + } else { + mBinderService.setNotificationListenerAccessGrantedForUser( + cn, Integer.parseInt(userId), true); + } + } + break; + case "disallow_listener": { + ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); + if (cn == null) { + pw.println("Invalid listener - must be a ComponentName"); + return -1; + } + String userId = getNextArg(); + if (userId == null) { + mBinderService.setNotificationListenerAccessGranted(cn, false); + } else { + mBinderService.setNotificationListenerAccessGrantedForUser( + cn, Integer.parseInt(userId), false); + } + } + break; + case "allow_assistant": { + ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); + if (cn == null) { + pw.println("Invalid assistant - must be a ComponentName"); + return -1; + } + mBinderService.setNotificationAssistantAccessGranted(cn, true); + } + break; + case "disallow_assistant": { + ComponentName cn = ComponentName.unflattenFromString(getNextArgRequired()); + if (cn == null) { + pw.println("Invalid assistant - must be a ComponentName"); + return -1; + } + mBinderService.setNotificationAssistantAccessGranted(cn, false); + } + break; + case "suspend_package": { + // only use for testing + mDirectService.simulatePackageSuspendBroadcast(true, getNextArgRequired()); + } + break; + case "unsuspend_package": { + // only use for testing + mDirectService.simulatePackageSuspendBroadcast(false, getNextArgRequired()); + } + break; + case "post": + case "notify": + doNotify(pw); + break; + default: + return handleDefaultCommands(cmd); + } + } catch (Exception e) { + pw.println("Error occurred. Check logcat for details. " + e.getMessage()); + Slog.e(NotificationManagerService.TAG, "Error running shell command", e); + } + return 0; + } + + void ensureChannel() throws RemoteException { + final int uid = Binder.getCallingUid(); + final int userid = UserHandle.getCallingUserId(); + final long token = Binder.clearCallingIdentity(); + try { + if (mBinderService.getNotificationChannelForPackage(NOTIFICATION_PACKAGE, + uid, CHANNEL_ID, false) == null) { + final NotificationChannel chan = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, + CHANNEL_IMP); + Slog.v(NotificationManagerService.TAG, + "creating shell channel for user " + userid + " uid " + uid + ": " + chan); + mBinderService.createNotificationChannelsForPackage(NOTIFICATION_PACKAGE, uid, + new ParceledListSlice<NotificationChannel>( + Collections.singletonList(chan))); + Slog.v(NotificationManagerService.TAG, "created channel: " + + mBinderService.getNotificationChannelForPackage(NOTIFICATION_PACKAGE, + uid, CHANNEL_ID, false)); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + Icon parseIcon(Resources res, String encoded) throws IllegalArgumentException { + if (TextUtils.isEmpty(encoded)) return null; + if (encoded.startsWith("/")) { + encoded = "file://" + encoded; + } + if (encoded.startsWith("http:") + || encoded.startsWith("https:") + || encoded.startsWith("content:") + || encoded.startsWith("file:") + || encoded.startsWith("android.resource:")) { + Uri asUri = Uri.parse(encoded); + return Icon.createWithContentUri(asUri); + } else if (encoded.startsWith("@")) { + final int resid = res.getIdentifier(encoded.substring(1), + "drawable", "android"); + if (resid != 0) { + return Icon.createWithResource(res, resid); + } + } else if (encoded.startsWith("data:")) { + encoded = encoded.substring(encoded.indexOf(',') + 1); + byte[] bits = android.util.Base64.decode(encoded, android.util.Base64.DEFAULT); + return Icon.createWithData(bits, 0, bits.length); + } + return null; + } + + private int doNotify(PrintWriter pw) throws RemoteException, URISyntaxException { + final Context context = mDirectService.getContext(); + final Resources res = context.getResources(); + final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID); + String opt; + + boolean verbose = false; + Notification.BigPictureStyle bigPictureStyle = null; + Notification.BigTextStyle bigTextStyle = null; + Notification.InboxStyle inboxStyle = null; + Notification.MediaStyle mediaStyle = null; + Notification.MessagingStyle messagingStyle = null; + + Icon smallIcon = null; + while ((opt = getNextOption()) != null) { + boolean large = false; + switch (opt) { + case "-v": + case "--verbose": + verbose = true; + break; + case "-t": + case "--title": + case "title": + builder.setContentTitle(getNextArgRequired()); + break; + case "-I": + case "--large-icon": + case "--largeicon": + case "largeicon": + case "large-icon": + large = true; + // fall through + case "-i": + case "--icon": + case "icon": + final String iconSpec = getNextArgRequired(); + final Icon icon = parseIcon(res, iconSpec); + if (icon == null) { + pw.println("error: invalid icon: " + iconSpec); + return -1; + } + if (large) { + builder.setLargeIcon(icon); + large = false; + } else { + smallIcon = icon; + } + break; + case "-c": + case "--content-intent": + case "content-intent": + case "--intent": + case "intent": + String intentKind = null; + switch (peekNextArg()) { + case "broadcast": + case "service": + case "activity": + intentKind = getNextArg(); + } + final Intent intent = Intent.parseCommandArgs(this, null); + if (intent.getData() == null) { + // force unique intents unless you know what you're doing + intent.setData(Uri.parse("xyz:" + System.currentTimeMillis())); + } + final PendingIntent pi; + if ("broadcast".equals(intentKind)) { + pi = PendingIntent.getBroadcastAsUser( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, + UserHandle.CURRENT); + } else if ("service".equals(intentKind)) { + pi = PendingIntent.getService( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } else { + pi = PendingIntent.getActivityAsUser( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, null, + UserHandle.CURRENT); + } + builder.setContentIntent(pi); + break; + case "-S": + case "--style": + final String styleSpec = getNextArgRequired().toLowerCase(); + switch (styleSpec) { + case "bigtext": + bigTextStyle = new Notification.BigTextStyle(); + builder.setStyle(bigTextStyle); + break; + case "bigpicture": + bigPictureStyle = new Notification.BigPictureStyle(); + builder.setStyle(bigPictureStyle); + break; + case "inbox": + inboxStyle = new Notification.InboxStyle(); + builder.setStyle(inboxStyle); + break; + case "messaging": + String name = "You"; + if ("--user".equals(peekNextArg())) { + getNextArg(); + name = getNextArgRequired(); + } + messagingStyle = new Notification.MessagingStyle( + new Person.Builder().setName(name).build()); + builder.setStyle(messagingStyle); + break; + case "media": + mediaStyle = new Notification.MediaStyle(); + builder.setStyle(mediaStyle); + break; + default: + throw new IllegalArgumentException( + "unrecognized notification style: " + styleSpec); + } + break; + case "--bigText": case "--bigtext": case "--big-text": + if (bigTextStyle == null) { + throw new IllegalArgumentException("--bigtext requires --style bigtext"); + } + bigTextStyle.bigText(getNextArgRequired()); + break; + case "--picture": + if (bigPictureStyle == null) { + throw new IllegalArgumentException("--picture requires --style bigpicture"); + } + final String pictureSpec = getNextArgRequired(); + final Icon pictureAsIcon = parseIcon(res, pictureSpec); + if (pictureAsIcon == null) { + throw new IllegalArgumentException("bad picture spec: " + pictureSpec); + } + final Drawable d = pictureAsIcon.loadDrawable(context); + if (d instanceof BitmapDrawable) { + bigPictureStyle.bigPicture(((BitmapDrawable) d).getBitmap()); + } else { + throw new IllegalArgumentException("not a bitmap: " + pictureSpec); + } + break; + case "--line": + if (inboxStyle == null) { + throw new IllegalArgumentException("--line requires --style inbox"); + } + inboxStyle.addLine(getNextArgRequired()); + break; + case "--message": + if (messagingStyle == null) { + throw new IllegalArgumentException( + "--message requires --style messaging"); + } + String arg = getNextArgRequired(); + String[] parts = arg.split(":", 2); + if (parts.length > 1) { + messagingStyle.addMessage(parts[1], System.currentTimeMillis(), + parts[0]); + } else { + messagingStyle.addMessage(parts[0], System.currentTimeMillis(), + new String[]{ + messagingStyle.getUserDisplayName().toString(), + "Them" + }[messagingStyle.getMessages().size() % 2]); + } + break; + case "--conversation": + if (messagingStyle == null) { + throw new IllegalArgumentException( + "--conversation requires --style messaging"); + } + messagingStyle.setConversationTitle(getNextArgRequired()); + break; + case "-h": + case "--help": + case "--wtf": + default: + pw.println(NOTIFY_USAGE); + return 0; + } + } + + final String tag = getNextArg(); + final String text = getNextArg(); + if (tag == null || text == null) { + pw.println(NOTIFY_USAGE); + return -1; + } + + builder.setContentText(text); + + if (smallIcon == null) { + // uh oh, let's substitute something + builder.setSmallIcon(com.android.internal.R.drawable.stat_notify_chat); + } else { + builder.setSmallIcon(smallIcon); + } + + ensureChannel(); + + final Notification n = builder.build(); + pw.println("posting:\n " + n); + Slog.v("NotificationManager", "posting: " + n); + + final int userId = UserHandle.getCallingUserId(); + final long token = Binder.clearCallingIdentity(); + try { + mBinderService.enqueueNotificationWithTag( + NOTIFICATION_PACKAGE, "android", + tag, NOTIFICATION_ID, + n, userId); + } finally { + Binder.restoreCallingIdentity(token); + } + + if (verbose) { + NotificationRecord nr = mDirectService.findNotificationLocked( + NOTIFICATION_PACKAGE, tag, NOTIFICATION_ID, userId); + for (int tries = 3; tries-- > 0; ) { + if (nr != null) break; + try { + pw.println("waiting for notification to post..."); + Thread.sleep(500); + } catch (InterruptedException e) { + } + nr = mDirectService.findNotificationLocked( + NOTIFICATION_PACKAGE, tag, NOTIFICATION_ID, userId); + } + if (nr == null) { + pw.println("warning: couldn't find notification after enqueueing"); + } else { + pw.println("posted: "); + nr.dump(pw, " ", context, false); + } + } + + return 0; + } + + @Override + public void onHelp() { + getOutPrintWriter().println(USAGE); + } +} + diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index f01d343948ea..e5b1878650d3 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -558,9 +558,7 @@ public class ZenModeHelper { rule.conditionId = automaticZenRule.getConditionId(); rule.enabled = automaticZenRule.isEnabled(); rule.modified = automaticZenRule.isModified(); - if (automaticZenRule.getZenPolicy() != null) { - rule.zenPolicy = automaticZenRule.getZenPolicy(); - } + rule.zenPolicy = automaticZenRule.getZenPolicy(); rule.zenMode = NotificationManager.zenModeFromInterruptionFilter( automaticZenRule.getInterruptionFilter(), Global.ZEN_MODE_OFF); } diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index ee067460cc45..2b4ec03b98fd 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -179,13 +179,19 @@ final class OverlayManagerSettings { List<OverlayInfo> getOverlaysForTarget(@NonNull final String targetPackageName, final int userId) { + // Static RROs targeting "android" are loaded from AssetManager, and so they should be + // ignored in OverlayManagerService. return selectWhereTarget(targetPackageName, userId) + .filter((i) -> !(i.isStatic() && "android".equals(i.getTargetPackageName()))) .map(SettingsItem::getOverlayInfo) .collect(Collectors.toList()); } ArrayMap<String, List<OverlayInfo>> getOverlaysForUser(final int userId) { + // Static RROs targeting "android" are loaded from AssetManager, and so they should be + // ignored in OverlayManagerService. return selectWhereUser(userId) + .filter((i) -> !(i.isStatic() && "android".equals(i.getTargetPackageName()))) .map(SettingsItem::getOverlayInfo) .collect(Collectors.groupingBy(info -> info.targetPackageName, ArrayMap::new, Collectors.toList())); diff --git a/services/core/java/com/android/server/pm/ModuleInfoProvider.java b/services/core/java/com/android/server/pm/ModuleInfoProvider.java index 886cfb25eadd..642bfa2e70fd 100644 --- a/services/core/java/com/android/server/pm/ModuleInfoProvider.java +++ b/services/core/java/com/android/server/pm/ModuleInfoProvider.java @@ -24,8 +24,8 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.XmlResourceParser; -import android.os.Process; import android.os.RemoteException; +import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Slog; @@ -91,7 +91,7 @@ public class ModuleInfoProvider { final PackageInfo pi; try { pi = mPackageManager.getPackageInfo(packageName, - PackageManager.GET_META_DATA, Process.SYSTEM_UID); + PackageManager.GET_META_DATA, UserHandle.USER_SYSTEM); Context packageContext = mContext.createPackageContext(packageName, 0); packageResources = packageContext.getResources(); diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index e038f9b606bc..66eae5e42378 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -128,6 +128,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements private final Context mContext; private final PackageManagerService mPm; + private final StagingManager mStagingManager; private final PermissionManagerInternal mPermissionManager; private AppOpsManager mAppOps; @@ -163,12 +164,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @GuardedBy("mSessions") private final SparseArray<PackageInstallerSession> mSessions = new SparseArray<>(); - // STOPSHIP: This is a temporary mock implementation of staged sessions. This variable - // shouldn't be needed at all. - // TODO(b/118865310): Implement staged sessions logic. - @GuardedBy("mStagedSessions") - private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>(); - /** Historical sessions kept around for debugging purposes */ @GuardedBy("mSessions") private final List<String> mHistoricalSessions = new ArrayList<>(); @@ -204,6 +199,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements "package-session"); mSessionsDir = new File(Environment.getDataSystemDirectory(), "install_sessions"); mSessionsDir.mkdirs(); + + mStagingManager = new StagingManager(pm); } public void systemReady() { @@ -311,7 +308,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements final PackageInstallerSession session; try { session = PackageInstallerSession.readFromXml(in, mInternalCallback, - mContext, mPm, mInstallThread.getLooper(), mSessionsDir, this); + mContext, mPm, mInstallThread.getLooper(), mStagingManager, + mSessionsDir, this); currentSession = session; } catch (Exception e) { currentSession = null; @@ -536,17 +534,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this, - mInstallThread.getLooper(), sessionId, userId, installerPackageName, - callingUid, params, createdMillis, stageDir, stageCid, false, false, null, - SessionInfo.INVALID_ID); + mInstallThread.getLooper(), mStagingManager, sessionId, userId, + installerPackageName, callingUid, params, createdMillis, stageDir, stageCid, false, + false, null, SessionInfo.INVALID_ID); synchronized (mSessions) { mSessions.put(sessionId, session); } if (params.isStaged) { - synchronized (mStagedSessions) { - mStagedSessions.put(sessionId, session); - } + mStagingManager.createSession(session); } mCallbacks.notifySessionCreated(session.sessionId, session.userId); @@ -679,14 +675,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public ParceledListSlice<SessionInfo> getStagedSessions() { - final List<SessionInfo> result = new ArrayList<>(); - synchronized (mStagedSessions) { - for (int i = 0; i < mStagedSessions.size(); i++) { - final PackageInstallerSession session = mStagedSessions.valueAt(i); - result.add(session.generateInfo(false)); - } - } - return new ParceledListSlice<>(result); + return mStagingManager.getSessions(); } @Override @@ -1131,16 +1120,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements mInstallHandler.post(new Runnable() { @Override public void run() { - // TODO(b/118865310): remove this mock implementation. if (session.isStaged()) { - // If the session is aborted, don't keep it in memory. Only store - // sessions successfully staged. if (!success) { - synchronized (mStagedSessions) { - mStagedSessions.remove(session.sessionId); - } - } else { - return; + mStagingManager.abortSession(session); } } synchronized (mSessions) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 0d0db9457672..d290f3f34909 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -105,6 +105,7 @@ import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter; +import com.android.server.pm.dex.DexManager; import libcore.io.IoUtils; @@ -174,6 +175,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private final PackageManagerService mPm; private final Handler mHandler; private final PackageSessionProvider mSessionProvider; + private final StagingManager mStagingManager; final int sessionId; final int userId; @@ -396,7 +398,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { public PackageInstallerSession(PackageInstallerService.InternalCallback callback, Context context, PackageManagerService pm, - PackageSessionProvider sessionProvider, Looper looper, + PackageSessionProvider sessionProvider, Looper looper, StagingManager stagingManager, int sessionId, int userId, String installerPackageName, int installerUid, SessionParams params, long createdMillis, File stageDir, String stageCid, boolean prepared, boolean sealed, @@ -406,6 +408,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mPm = pm; mSessionProvider = sessionProvider; mHandler = new Handler(looper, mHandlerCallback); + mStagingManager = stagingManager; this.sessionId = sessionId; this.userId = userId; @@ -699,9 +702,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { switch (Binder.getCallingUid()) { case android.os.Process.SHELL_UID: case android.os.Process.ROOT_UID: + case android.os.Process.SYSTEM_UID: break; default: - throw new SecurityException("Reverse mode only supported from shell"); + throw new SecurityException( + "Reverse mode only supported from shell or system"); } // In "reverse" mode, we're streaming data ourselves from the @@ -1063,8 +1068,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return; } if (isStaged()) { - // STOPSHIP: implement staged sessions - mStagedSessionReady = true; + mStagingManager.commitSession(this); dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null); return; } @@ -1082,7 +1086,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (activeSession != null) { if ((activeSession.getSessionParams().installFlags & PackageManager.INSTALL_APEX) != 0) { - // TODO(b/118865310): Add exception to this case for staged installs throw new PackageManagerException( PackageManager.INSTALL_FAILED_INTERNAL_ERROR, "Atomic install is not supported for APEX packages."); @@ -1592,6 +1595,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } } + if (baseApk.preferCodeIntegrity) { + for (File file : mResolvedStagedFiles) { + if (file.getName().endsWith(".apk") + && !DexManager.auditUncompressedCodeInApk(file.getPath())) { + throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, + "Some code are not uncompressed and aligned correctly for " + + mPackageName); + } + } + } if (baseApk.isSplitRequired && stagedSplits.size() <= 1) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT, "Missing split for " + mPackageName); @@ -1949,6 +1962,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mCallback.onSessionFinished(this, success); } + void setStagedSessionReady() { + synchronized (mLock) { + mStagedSessionReady = true; + mStagedSessionApplied = false; + mStagedSessionFailed = false; + mStagedSessionErrorCode = SessionInfo.NO_ERROR; + } + } + private void destroyInternal() { synchronized (mLock) { mSealed = true; @@ -2150,7 +2172,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // can have a complete session for the constructor public static PackageInstallerSession readFromXml(@NonNull XmlPullParser in, @NonNull PackageInstallerService.InternalCallback callback, @NonNull Context context, - @NonNull PackageManagerService pm, Looper installerThread, @NonNull File sessionsDir, + @NonNull PackageManagerService pm, Looper installerThread, + @NonNull StagingManager stagingManager, @NonNull File sessionsDir, @NonNull PackageSessionProvider sessionProvider) throws IOException, XmlPullParserException { final int sessionId = readIntAttribute(in, ATTR_SESSION_ID); @@ -2194,8 +2217,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { params.appIconLastModified = appIconFile.lastModified(); } return new PackageInstallerSession(callback, context, pm, sessionProvider, - installerThread, sessionId, userId, installerPackageName, installerUid, - params, createdMillis, stageDir, stageCid, prepared, sealed, + installerThread, stagingManager, sessionId, userId, installerPackageName, + installerUid, params, createdMillis, stageDir, stageCid, prepared, sealed, EMPTY_CHILD_SESSION_ARRAY, parentSessionId); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9f1b922e226f..136c7c91749e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -296,6 +296,7 @@ import com.android.server.EventLogTags; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.LockGuard; +import com.android.server.PackageWatchdog; import com.android.server.ServiceThread; import com.android.server.SystemConfig; import com.android.server.SystemServerInitThreadPool; @@ -447,6 +448,7 @@ public class PackageManagerService extends IPackageManager.Stub private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; private static final int SHELL_UID = Process.SHELL_UID; private static final int SE_UID = Process.SE_UID; + private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID; static final int SCAN_NO_DEX = 1 << 0; static final int SCAN_UPDATE_SIGNATURE = 1 << 1; @@ -545,6 +547,12 @@ public class PackageManagerService extends IPackageManager.Stub private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; /** + * The default duration to wait for rollback to be enabled in + * milliseconds. + */ + private static final long DEFAULT_ENABLE_ROLLBACK_TIMEOUT = 10 * 1000; + + /** * The default response for package verification timeout. * * This can be either PackageManager.VERIFICATION_ALLOW or @@ -864,6 +872,9 @@ public class PackageManagerService extends IPackageManager.Stub /** List of packages waiting for verification. */ final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>(); + /** List of packages waiting for rollback to be enabled. */ + final SparseArray<InstallParams> mPendingEnableRollback = new SparseArray<>(); + final PackageInstallerService mInstallerService; final ArtManagerService mArtManagerService; @@ -884,6 +895,9 @@ public class PackageManagerService extends IPackageManager.Stub /** Token for keys in mPendingVerification. */ private int mPendingVerificationToken = 0; + /** Token for keys in mPendingEnableRollback. */ + private int mPendingEnableRollbackToken = 0; + volatile boolean mSystemReady; volatile boolean mSafeMode; volatile boolean mHasSystemUidErrors; @@ -1255,6 +1269,8 @@ public class PackageManagerService extends IPackageManager.Stub static final int INTENT_FILTER_VERIFIED = 18; static final int WRITE_PACKAGE_LIST = 19; static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20; + static final int ENABLE_ROLLBACK_STATUS = 21; + static final int ENABLE_ROLLBACK_TIMEOUT = 22; static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds @@ -1478,14 +1494,13 @@ public class PackageManagerService extends IPackageManager.Stub final PackageVerificationState state = mPendingVerification.get(verificationId); if ((state != null) && !state.timeoutExtended()) { - final InstallArgs args = state.getInstallArgs(); + final InstallParams params = state.getInstallParams(); + final InstallArgs args = params.mArgs; final Uri originUri = Uri.fromFile(args.origin.resolvedFile); Slog.i(TAG, "Verification timed out for " + originUri); mPendingVerification.remove(verificationId); - int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; - final UserHandle user = args.getUser(); if (getDefaultVerificationResponse(user) == PackageManager.VERIFICATION_ALLOW) { @@ -1494,16 +1509,16 @@ public class PackageManagerService extends IPackageManager.Stub PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); broadcastPackageVerified(verificationId, originUri, PackageManager.VERIFICATION_ALLOW, user); - ret = args.copyApk(); } else { broadcastPackageVerified(verificationId, originUri, PackageManager.VERIFICATION_REJECT, user); + params.setReturnCode( + PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE); } Trace.asyncTraceEnd( TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); - - processPendingInstall(args, ret); + params.handleVerificationFinished(); } break; } @@ -1523,22 +1538,22 @@ public class PackageManagerService extends IPackageManager.Stub if (state.isVerificationComplete()) { mPendingVerification.remove(verificationId); - final InstallArgs args = state.getInstallArgs(); + final InstallParams params = state.getInstallParams(); + final InstallArgs args = params.mArgs; final Uri originUri = Uri.fromFile(args.origin.resolvedFile); - int ret; if (state.isInstallAllowed()) { broadcastPackageVerified(verificationId, originUri, - response.code, state.getInstallArgs().getUser()); - ret = args.copyApk(); + response.code, args.getUser()); } else { - ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; + params.setReturnCode( + PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE); } Trace.asyncTraceEnd( TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); - processPendingInstall(args, ret); + params.handleVerificationFinished(); } break; @@ -1598,6 +1613,49 @@ public class PackageManagerService extends IPackageManager.Stub (InstantAppRequest) msg.obj, mInstantAppInstallerActivity, mHandler); + break; + } + case ENABLE_ROLLBACK_STATUS: { + final int enableRollbackToken = msg.arg1; + final int enableRollbackCode = msg.arg2; + InstallParams params = mPendingEnableRollback.get(enableRollbackToken); + if (params == null) { + Slog.w(TAG, "Invalid rollback enabled token " + + enableRollbackToken + " received"); + break; + } + + mPendingEnableRollback.remove(enableRollbackToken); + + if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) { + final InstallArgs args = params.mArgs; + final Uri originUri = Uri.fromFile(args.origin.resolvedFile); + Slog.w(TAG, "Failed to enable rollback for " + originUri); + Slog.w(TAG, "Continuing with installation of " + originUri); + } + + Trace.asyncTraceEnd( + TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken); + + params.handleRollbackEnabled(); + break; + } + case ENABLE_ROLLBACK_TIMEOUT: { + final int enableRollbackToken = msg.arg1; + final InstallParams params = mPendingEnableRollback.get(enableRollbackToken); + if (params != null) { + final InstallArgs args = params.mArgs; + final Uri originUri = Uri.fromFile(args.origin.resolvedFile); + + Slog.w(TAG, "Enable rollback timed out for " + originUri); + mPendingEnableRollback.remove(enableRollbackToken); + + Slog.w(TAG, "Continuing with installation of " + originUri); + Trace.asyncTraceEnd( + TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken); + params.handleRollbackEnabled(); + } + break; } } } @@ -2171,6 +2229,8 @@ public class PackageManagerService extends IPackageManager.Stub ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.se", SE_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); + mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID, + ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); String separateProcesses = SystemProperties.get("debug.separate_processes"); if (separateProcesses != null && separateProcesses.length() > 0) { @@ -5567,12 +5627,18 @@ public class PackageManagerService extends IPackageManager.Stub * were updated, return true. */ private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { - final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); + return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg)); + } + + private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) { return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; } private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { - final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); + return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg)); + } + + private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) { return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; } @@ -8336,11 +8402,12 @@ public class PackageManagerService extends IPackageManager.Stub // directory and not the APK file. final long lastModifiedTime = mIsPreNMR1Upgrade ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg); + final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(pkg); if (ps != null && !forceCollect && ps.codePathString.equals(pkg.codePath) && ps.timeStamp == lastModifiedTime - && !isCompatSignatureUpdateNeeded(pkg) - && !isRecoverSignatureUpdateNeeded(pkg)) { + && !isCompatSignatureUpdateNeeded(settingsVersionForPackage) + && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) { if (ps.signatures.mSigningDetails.signatures != null && ps.signatures.mSigningDetails.signatures.length != 0 && ps.signatures.mSigningDetails.signatureSchemeVersion @@ -8741,15 +8808,20 @@ public class PackageManagerService extends IPackageManager.Stub if (scanResult.success) { synchronized (mPackages) { try { - final Map<String, ReconciledPackage> reconcileResult = - reconcilePackagesLocked(new ReconcileRequest( - Collections.singletonMap(scanResult.pkgSetting.name, - scanResult), + final String pkgName = scanResult.pkgSetting.name; + final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked( + new ReconcileRequest( + Collections.singletonMap(pkgName, scanResult), mSharedLibraries, - mPackages)); + mPackages, + Collections.singletonMap( + pkgName, getSettingsVersionForPackage(pkg)), + Collections.singletonMap(pkgName, + getSharedLibLatestVersionSetting(scanResult))), + mSettings.mKeySetManagerService); prepareScanResultLocked(scanResult); commitReconciledScanResultLocked( - reconcileResult.get(scanResult.pkgSetting.name)); + reconcileResult.get(pkgName)); } catch (PackageManagerException e) { unprepareScanResultLocked(scanResult); throw e; @@ -9402,10 +9474,26 @@ public class PackageManagerService extends IPackageManager.Stub return null; } + + @Nullable + private PackageSetting getSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) { + PackageSetting sharedLibPackage = null; + synchronized (mPackages) { + final SharedLibraryInfo latestSharedLibraVersionLPr = + getLatestSharedLibraVersionLPr(scanResult.pkgSetting.pkg); + if (latestSharedLibraVersionLPr != null) { + sharedLibPackage = mSettings.getPackageLPr( + latestSharedLibraVersionLPr.getPackageName()); + } + } + return sharedLibPackage; + } + public void shutdown() { mPackageUsage.writeNow(mPackages); mCompilerStats.writeNow(); mDexManager.writePackageDexUsageNow(); + PackageWatchdog.getInstance(mContext).writeNow(); // This is the last chance to write out pending restriction settings synchronized (mPackages) { @@ -10219,8 +10307,7 @@ public class PackageManagerService extends IPackageManager.Stub * possible and the system is not left in an inconsistent state. */ @GuardedBy({"mPackages", "mInstallLock"}) - private void commitReconciledScanResultLocked(@NonNull ReconciledPackage reconciledPkg) - throws PackageManagerException { + private void commitReconciledScanResultLocked(@NonNull ReconciledPackage reconciledPkg) { final ScanResult result = reconciledPkg.scanResult; final ScanRequest request = result.request; final PackageParser.Package pkg = request.pkg; @@ -10229,7 +10316,6 @@ public class PackageManagerService extends IPackageManager.Stub final @ScanFlags int scanFlags = request.scanFlags; final PackageSetting oldPkgSetting = request.oldPkgSetting; final PackageSetting originalPkgSetting = request.originalPkgSetting; - final PackageSetting disabledPkgSetting = request.disabledPkgSetting; final UserHandle user = request.user; final String realPkgName = request.realPkgName; final List<String> changedAbiCodePath = result.changedAbiCodePath; @@ -10269,115 +10355,15 @@ public class PackageManagerService extends IPackageManager.Stub executeSharedLibrariesUpdateLPr(pkg, null, reconciledPkg.collectedSharedLibraryInfos); } - // All versions of a static shared library are referenced with the same - // package name. Internally, we use a synthetic package name to allow - // multiple versions of the same shared library to be installed. So, - // we need to generate the synthetic package name of the latest shared - // library in order to compare signatures. - PackageSetting signatureCheckPs = pkgSetting; - if (pkg.applicationInfo.isStaticSharedLibrary()) { - SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(pkg); - if (libraryInfo != null) { - signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName()); - } - } - final KeySetManagerService ksms = mSettings.mKeySetManagerService; - if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) { - if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) { - // We just determined the app is signed correctly, so bring - // over the latest parsed certs. - pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails; - } else { - if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { - throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, - "Package " + pkg.packageName + " upgrade keys do not match the " - + "previously installed version"); - } else { - pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails; - String msg = "System package " + pkg.packageName - + " signature changed; retaining data."; - reportSettingsProblem(Log.WARN, msg); - } - } - } else { - try { - final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg); - final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg); - final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting, - pkg.mSigningDetails, compareCompat, compareRecover); - // The new KeySets will be re-added later in the scanning process. - if (compatMatch) { - synchronized (mPackages) { - ksms.removeAppKeySetDataLPw(pkg.packageName); - } - } - // We just determined the app is signed correctly, so bring - // over the latest parsed certs. - pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails; - - - // if this is is a sharedUser, check to see if the new package is signed by a newer - // signing certificate than the existing one, and if so, copy over the new details - if (signatureCheckPs.sharedUser != null) { - if (pkg.mSigningDetails.hasAncestor( - signatureCheckPs.sharedUser.signatures.mSigningDetails)) { - signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails; - } - if (signatureCheckPs.sharedUser.signaturesChanged == null) { - signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE; - } - } - } catch (PackageManagerException e) { - if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { - throw e; - } - // The signature has changed, but this package is in the system - // image... let's recover! - pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails; - - // If the system app is part of a shared user we allow that shared user to change - // signatures as well as part of an OTA. We still need to verify that the signatures - // are consistent within the shared user for a given boot, so only allow updating - // the signatures on the first package scanned for the shared user (i.e. if the - // signaturesChanged state hasn't been initialized yet in SharedUserSetting). - if (signatureCheckPs.sharedUser != null) { - if (signatureCheckPs.sharedUser.signaturesChanged != null && - compareSignatures( - signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures, - pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) { - if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 28) { - // Mismatched signatures is an error and silently skipping system - // packages will likely break the device in unforeseen ways. However, - // we allow the device to boot anyway because, prior to P, vendors were - // not expecting the platform to crash in this situation. - throw new PackageManagerException( - INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, - "Signature mismatch for shared user: " + pkgSetting.sharedUser); - } else { - // Treat mismatched signatures on system packages using a shared UID as - // fatal for the system overall, rather than just failing to install - // whichever package happened to be scanned later. - throw new IllegalStateException("Signature mismatch on system package " - + pkg.packageName + " for shared user " + pkgSetting.sharedUser); - } - } - - signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails; - signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE; - } - // File a report about this. - String msg = "System package " + pkg.packageName - + " signature changed; retaining data."; - reportSettingsProblem(Log.WARN, msg); - } catch (IllegalArgumentException e) { - // should never happen: certs matched when checking, but not when comparing - // old to new for sharedUser - throw new RuntimeException( - "Signing certificates comparison made on incomparable signing details" - + " but somehow passed verifySignatures!", e); - } + if (reconciledPkg.removeAppKeySetData) { + ksms.removeAppKeySetDataLPw(pkg.packageName); + } + if (reconciledPkg.sharedUserSignaturesChanged) { + pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE; + pkgSetting.sharedUser.signatures.mSigningDetails = reconciledPkg.signingDetails; } + pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails; if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { // This package wants to adopt ownership of permissions from @@ -13037,20 +13023,26 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public boolean canSuspendPackageForUser(String packageName, int userId) { + public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) { mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, - "canSuspendPackageForUser"); + "getUnsuspendablePackagesForUser"); final int callingUid = Binder.getCallingUid(); if (UserHandle.getUserId(callingUid) != userId) { throw new SecurityException("Calling uid " + callingUid - + " cannot query canSuspendPackageForUser for user " + userId); + + " cannot query getUnsuspendablePackagesForUser for user " + userId); } + final ArraySet<String> unactionablePackages = new ArraySet<>(); final long identity = Binder.clearCallingIdentity(); try { - return canSuspendPackageForUserInternal(packageName, userId); + for (String packageName : packageNames) { + if (!canSuspendPackageForUserInternal(packageName, userId)) { + unactionablePackages.add(packageName); + } + } } finally { Binder.restoreCallingIdentity(identity); } + return unactionablePackages.toArray(new String[unactionablePackages.size()]); } private boolean canSuspendPackageForUserInternal(String packageName, int userId) { @@ -13295,6 +13287,13 @@ public class PackageManagerService extends IPackageManager.Stub } } + private void setEnableRollbackCode(int token, int enableRollbackCode) { + final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS); + msg.arg1 = token; + msg.arg2 = enableRollbackCode; + mHandler.sendMessage(msg); + } + @Override public void finishPackageInstall(int token, boolean didLaunch) { enforceSystemOrRoot("Only the system is allowed to finish installs"); @@ -13946,7 +13945,7 @@ public class PackageManagerService extends IPackageManager.Stub @NonNull private final ArrayList<InstallParams> mChildParams; @NonNull - private final Map<InstallArgs, Integer> mVerifiedState; + private final Map<InstallArgs, Integer> mCurrentState; MultiPackageInstallParams( @NonNull UserHandle user, @@ -13962,7 +13961,7 @@ public class PackageManagerService extends IPackageManager.Stub childParams.mParentInstallParams = this; this.mChildParams.add(childParams); } - this.mVerifiedState = new ArrayMap<>(mChildParams.size()); + this.mCurrentState = new ArrayMap<>(mChildParams.size()); } @Override @@ -13988,12 +13987,12 @@ public class PackageManagerService extends IPackageManager.Stub } void tryProcessInstallRequest(InstallArgs args, int currentStatus) { - mVerifiedState.put(args, currentStatus); + mCurrentState.put(args, currentStatus); boolean success = true; - if (mVerifiedState.size() != mChildParams.size()) { + if (mCurrentState.size() != mChildParams.size()) { return; } - for (Integer status : mVerifiedState.values()) { + for (Integer status : mCurrentState.values()) { if (status == PackageManager.INSTALL_UNKNOWN) { return; } else if (status != PackageManager.INSTALL_SUCCEEDED) { @@ -14001,8 +14000,8 @@ public class PackageManagerService extends IPackageManager.Stub break; } } - final List<InstallRequest> installRequests = new ArrayList<>(mVerifiedState.size()); - for (Map.Entry<InstallArgs, Integer> entry : mVerifiedState.entrySet()) { + final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size()); + for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) { installRequests.add(new InstallRequest(entry.getKey(), createPackageInstalledInfo(entry.getValue()))); } @@ -14019,6 +14018,8 @@ public class PackageManagerService extends IPackageManager.Stub int installFlags; final String installerPackageName; final String volumeUuid; + private boolean mVerificationCompleted; + private boolean mEnableRollbackCompleted; private InstallArgs mArgs; int mRet; final String packageAbiOverride; @@ -14268,6 +14269,8 @@ public class PackageManagerService extends IPackageManager.Stub } final InstallArgs args = createInstallArgs(this); + mVerificationCompleted = true; + mEnableRollbackCompleted = true; mArgs = args; if (ret == PackageManager.INSTALL_SUCCEEDED) { @@ -14347,7 +14350,7 @@ public class PackageManagerService extends IPackageManager.Stub } final PackageVerificationState verificationState = new PackageVerificationState( - requiredUid, args); + requiredUid, this); mPendingVerification.append(verificationId, verificationState); @@ -14409,25 +14412,80 @@ public class PackageManagerService extends IPackageManager.Stub /* * We don't want the copy to proceed until verification - * succeeds, so null out this field. + * succeeds. */ - mArgs = null; + mVerificationCompleted = false; } - } else { - /* - * No package verification is enabled, so immediately start - * the remote call to initiate copy using temporary file. - */ - ret = args.copyApk(); + } + + if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { + // TODO(ruhler) b/112431924: Don't do this in case of 'move'? + final int enableRollbackToken = mPendingEnableRollbackToken++; + Trace.asyncTraceBegin( + TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken); + mPendingEnableRollback.append(enableRollbackToken, this); + + // TODO(ruhler) b/112431924: What user? Test for multi-user. + Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK); + enableRollbackIntent.putExtra( + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, + enableRollbackToken); + enableRollbackIntent.putExtra( + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS, + installFlags); + enableRollbackIntent.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), + PACKAGE_MIME_TYPE); + enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, getUser(), + android.Manifest.permission.PACKAGE_ROLLBACK_AGENT, + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + // TODO(ruhler) b/112431924 Have a configurable setting to + // allow changing the timeout and fall back to the default + // if no such specified. + final Message msg = mHandler.obtainMessage( + ENABLE_ROLLBACK_TIMEOUT); + msg.arg1 = enableRollbackToken; + mHandler.sendMessageDelayed(msg, + DEFAULT_ENABLE_ROLLBACK_TIMEOUT); + } + }, null, 0, null, null); + + mEnableRollbackCompleted = false; } } mRet = ret; } + void setReturnCode(int ret) { + if (mRet == PackageManager.INSTALL_SUCCEEDED) { + // Only update mRet if it was previously INSTALL_SUCCEEDED to + // ensure we do not overwrite any previous failure results. + mRet = ret; + } + } + + void handleVerificationFinished() { + mVerificationCompleted = true; + handleReturnCode(); + } + + void handleRollbackEnabled() { + // TODO(ruhler) b/112431924: Consider halting the install if we + // couldn't enable rollback. + mEnableRollbackCompleted = true; + handleReturnCode(); + } + @Override void handleReturnCode() { - if (mArgs != null) { + if (mVerificationCompleted && mEnableRollbackCompleted) { + if (mRet == PackageManager.INSTALL_SUCCEEDED) { + mRet = mArgs.copyApk(); + } processPendingInstall(mArgs, mRet); } } @@ -15228,26 +15286,35 @@ public class PackageManagerService extends IPackageManager.Stub public final Map<String, InstallArgs> installArgs; public final Map<String, PackageInstalledInfo> installResults; public final Map<String, PrepareResult> preparedPackages; + public final Map<String, VersionInfo> versionInfos; + public final Map<String, PackageSetting> lastStaticSharedLibSettings; private ReconcileRequest(Map<String, ScanResult> scannedPackages, Map<String, InstallArgs> installArgs, Map<String, PackageInstalledInfo> installResults, Map<String, PrepareResult> preparedPackages, Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource, - Map<String, PackageParser.Package> allPackages) { + Map<String, PackageParser.Package> allPackages, + Map<String, VersionInfo> versionInfos, + Map<String, PackageSetting> lastStaticSharedLibSettings) { this.scannedPackages = scannedPackages; this.installArgs = installArgs; this.installResults = installResults; this.preparedPackages = preparedPackages; this.sharedLibrarySource = sharedLibrarySource; this.allPackages = allPackages; + this.versionInfos = versionInfos; + this.lastStaticSharedLibSettings = lastStaticSharedLibSettings; } private ReconcileRequest(Map<String, ScanResult> scannedPackages, Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource, - Map<String, PackageParser.Package> allPackages) { + Map<String, PackageParser.Package> allPackages, + Map<String, VersionInfo> versionInfos, + Map<String, PackageSetting> lastStaticSharedLibSettings) { this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(), - Collections.emptyMap(), sharedLibrarySource, allPackages); + Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos, + lastStaticSharedLibSettings); } } private static class ReconcileFailure extends PackageManagerException { @@ -15257,6 +15324,9 @@ public class PackageManagerService extends IPackageManager.Stub ReconcileFailure(int reason, String message) { super(reason, "Reconcile failed: " + message); } + ReconcileFailure(PackageManagerException e) { + this(e.error, e.getMessage()); + } } /** @@ -15272,13 +15342,19 @@ public class PackageManagerService extends IPackageManager.Stub @Nullable public final InstallArgs installArgs; public final DeletePackageAction deletePackageAction; public final List<SharedLibraryInfo> allowedSharedLibraryInfos; + public final SigningDetails signingDetails; + public final boolean sharedUserSignaturesChanged; public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos; + public final boolean removeAppKeySetData; private ReconciledPackage(InstallArgs installArgs, PackageSetting pkgSetting, PackageInstalledInfo installResult, PrepareResult prepareResult, ScanResult scanResult, DeletePackageAction deletePackageAction, - List<SharedLibraryInfo> allowedSharedLibraryInfos) { + List<SharedLibraryInfo> allowedSharedLibraryInfos, + SigningDetails signingDetails, + boolean sharedUserSignaturesChanged, + boolean removeAppKeySetData) { this.installArgs = installArgs; this.pkgSetting = pkgSetting; this.installResult = installResult; @@ -15286,6 +15362,9 @@ public class PackageManagerService extends IPackageManager.Stub this.scanResult = scanResult; this.deletePackageAction = deletePackageAction; this.allowedSharedLibraryInfos = allowedSharedLibraryInfos; + this.signingDetails = signingDetails; + this.sharedUserSignaturesChanged = sharedUserSignaturesChanged; + this.removeAppKeySetData = removeAppKeySetData; } public boolean hasDynamicSharedLibraries() { @@ -15296,7 +15375,7 @@ public class PackageManagerService extends IPackageManager.Stub @GuardedBy("mPackages") private static Map<String, ReconciledPackage> reconcilePackagesLocked( - final ReconcileRequest request) + final ReconcileRequest request, KeySetManagerService ksms) throws ReconcileFailure { final Map<String, ScanResult> scannedPackages = request.scannedPackages; @@ -15357,10 +15436,133 @@ public class PackageManagerService extends IPackageManager.Stub deletePackageAction = null; } + final int scanFlags = scanResult.request.scanFlags; + final int parseFlags = scanResult.request.parseFlags; + final PackageParser.Package pkg = scanResult.request.pkg; + + final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting; + final PackageSetting lastStaticSharedLibSetting = + request.lastStaticSharedLibSettings.get(installPackageName); + final PackageSetting signatureCheckPs = + (prepareResult != null && lastStaticSharedLibSetting != null) + ? lastStaticSharedLibSetting + : scanResult.pkgSetting; + boolean removeAppKeySetData = false; + boolean sharedUserSignaturesChanged = false; + SigningDetails signingDetails = null; + if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) { + if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) { + // We just determined the app is signed correctly, so bring + // over the latest parsed certs. + } else { + if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { + throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, + "Package " + pkg.packageName + " upgrade keys do not match the " + + "previously installed version"); + } else { + String msg = "System package " + pkg.packageName + + " signature changed; retaining data."; + reportSettingsProblem(Log.WARN, msg); + } + } + signingDetails = pkg.mSigningDetails; + } else { + try { + final VersionInfo versionInfo = request.versionInfos.get(installPackageName); + final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo); + final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo); + final boolean compatMatch = verifySignatures(signatureCheckPs, + disabledPkgSetting, pkg.mSigningDetails, compareCompat, compareRecover); + // The new KeySets will be re-added later in the scanning process. + if (compatMatch) { + removeAppKeySetData = true; + } + // We just determined the app is signed correctly, so bring + // over the latest parsed certs. + signingDetails = pkg.mSigningDetails; + + + // if this is is a sharedUser, check to see if the new package is signed by a + // newer + // signing certificate than the existing one, and if so, copy over the new + // details + if (signatureCheckPs.sharedUser != null) { + if (pkg.mSigningDetails.hasAncestor( + signatureCheckPs.sharedUser.signatures.mSigningDetails)) { + signatureCheckPs.sharedUser.signatures.mSigningDetails = + pkg.mSigningDetails; + } + if (signatureCheckPs.sharedUser.signaturesChanged == null) { + signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE; + } + } + } catch (PackageManagerException e) { + if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { + throw new ReconcileFailure(e); + } + signingDetails = pkg.mSigningDetails; + + // If the system app is part of a shared user we allow that shared user to + // change + // signatures as well as part of an OTA. We still need to verify that the + // signatures + // are consistent within the shared user for a given boot, so only allow + // updating + // the signatures on the first package scanned for the shared user (i.e. if the + // signaturesChanged state hasn't been initialized yet in SharedUserSetting). + if (signatureCheckPs.sharedUser != null) { + final Signature[] sharedUserSignatures = + signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures; + if (signatureCheckPs.sharedUser.signaturesChanged != null + && compareSignatures(sharedUserSignatures, + pkg.mSigningDetails.signatures) + != PackageManager.SIGNATURE_MATCH) { + if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 28) { + // Mismatched signatures is an error and silently skipping system + // packages will likely break the device in unforeseen ways. + // However, + // we allow the device to boot anyway because, prior to P, + // vendors were + // not expecting the platform to crash in this situation. + throw new ReconcileFailure( + INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, + "Signature mismatch for shared user: " + + scanResult.pkgSetting.sharedUser); + } else { + // Treat mismatched signatures on system packages using a shared + // UID as + // fatal for the system overall, rather than just failing to install + // whichever package happened to be scanned later. + throw new IllegalStateException( + "Signature mismatch on system package " + + pkg.packageName + " for shared user " + + scanResult.pkgSetting.sharedUser); + } + } + + sharedUserSignaturesChanged = true; + signatureCheckPs.sharedUser.signatures.mSigningDetails = + pkg.mSigningDetails; + signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE; + } + // File a report about this. + String msg = "System package " + pkg.packageName + + " signature changed; retaining data."; + reportSettingsProblem(Log.WARN, msg); + } catch (IllegalArgumentException e) { + // should never happen: certs matched when checking, but not when comparing + // old to new for sharedUser + throw new RuntimeException( + "Signing certificates comparison made on incomparable signing details" + + " but somehow passed verifySignatures!", e); + } + } + result.put(installPackageName, new ReconciledPackage(installArgs, scanResult.pkgSetting, res, request.preparedPackages.get(installPackageName), scanResult, - deletePackageAction, allowedSharedLibInfos)); + deletePackageAction, allowedSharedLibInfos, signingDetails, + sharedUserSignaturesChanged, removeAppKeySetData)); } for (String installPackageName : scannedPackages.keySet()) { @@ -15389,10 +15591,15 @@ public class PackageManagerService extends IPackageManager.Stub return result; } + /** + * Compare the newly scanned package with current system state to see which of its declared + * shared libraries should be allowed to be added to the system. + */ private static List<SharedLibraryInfo> getAllowedSharedLibInfos( ScanResult scanResult, Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) { - final PackageParser.Package pkg = scanResult.pkgSetting.pkg; + // Let's used the parsed package as scanResult.pkgSetting may be null + final PackageParser.Package pkg = scanResult.request.pkg; if (scanResult.staticSharedLibraryInfo == null && scanResult.dynamicSharedLibraryInfos == null) { return null; @@ -15424,8 +15631,12 @@ public class PackageManagerService extends IPackageManager.Stub // have allowed apps on the device which aren't compatible // with it. Better to just have the restriction here, be // conservative, and create many fewer cases that can negatively - // impact the user experience. - final PackageSetting sysPs = scanResult.request.disabledPkgSetting; + // impact the user experience. We may not yet have disabled the + // updated package yet, so be sure to grab the current setting if + // that's the case. + final PackageSetting sysPs = scanResult.request.disabledPkgSetting == null + ? scanResult.request.oldPkgSetting + : scanResult.request.disabledPkgSetting; if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) { if (name.equals(sysPs.pkg.libraryNames.get(j))) { @@ -15478,7 +15689,7 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy("mPackages") - private boolean commitPackagesLocked(final CommitRequest request) { + private void commitPackagesLocked(final CommitRequest request) { // TODO: remove any expected failures from this method; this should only be able to fail due // to unavoidable errors (I/O, etc.) for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) { @@ -15614,17 +15825,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - - - try { - prepareScanResultLocked(scanResult); - commitReconciledScanResultLocked(reconciledPkg); - } catch (PackageManagerException e) { - unprepareScanResultLocked(scanResult); - res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); - res.setError("Package couldn't be installed in " + pkg.codePath, e); - return false; - } + commitReconciledScanResultLocked(reconciledPkg); updateSettingsLI(pkg, reconciledPkg.installArgs.installerPackageName, request.mAllUsers, res, reconciledPkg.installArgs.user, reconciledPkg.installArgs.installReason); @@ -15649,7 +15850,6 @@ public class PackageManagerService extends IPackageManager.Stub updateInstantAppInstallerLocked(packageName); } } - return true; } /** @@ -15671,12 +15871,16 @@ public class PackageManagerService extends IPackageManager.Stub * * Failure at any phase will result in a full failure to install all packages. */ - @GuardedBy({"mInstallLock", "mPackages"}) + @GuardedBy("mInstallLock") private void installPackagesLI(List<InstallRequest> requests) { - final Map<String, ScanResult> scans = new ArrayMap<>(requests.size()); + final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size()); final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size()); final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size()); final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size()); + final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size()); + final Map<String, PackageSetting> lastStaticSharedLibSettings = + new ArrayMap<>(requests.size()); + boolean success = false; try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI"); for (InstallRequest request : requests) { @@ -15708,35 +15912,47 @@ public class PackageManagerService extends IPackageManager.Stub prepareResult.scanFlags, System.currentTimeMillis(), request.args.user); for (ScanResult result : scanResults) { - if (null != scans.put(result.pkgSetting.pkg.packageName, result)) { + if (null != preparedScans.put(result.pkgSetting.pkg.packageName, result)) { request.installResult.setError( PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE, "Duplicate package " + result.pkgSetting.pkg.packageName + " in multi-package install request."); return; } + prepareScanResultLocked(result); + versionInfos.put(result.pkgSetting.pkg.packageName, + getSettingsVersionForPackage(result.pkgSetting.pkg)); + if (result.staticSharedLibraryInfo != null) { + final PackageSetting sharedLibLatestVersionSetting = + getSharedLibLatestVersionSetting(result); + if (sharedLibLatestVersionSetting != null) { + lastStaticSharedLibSettings.put(result.pkgSetting.pkg.packageName, + sharedLibLatestVersionSetting); + } + } + prepareScanResultLocked(result); } } catch (PackageManagerException e) { request.installResult.setError("Scanning Failed.", e); return; } } - ReconcileRequest reconcileRequest = new ReconcileRequest(scans, installArgs, + ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs, installResults, prepareResults, mSharedLibraries, - Collections.unmodifiableMap(mPackages)); + Collections.unmodifiableMap(mPackages), versionInfos, + lastStaticSharedLibSettings); CommitRequest commitRequest = null; synchronized (mPackages) { Map<String, ReconciledPackage> reconciledPackages; try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages"); - reconciledPackages = reconcilePackagesLocked(reconcileRequest); + reconciledPackages = reconcilePackagesLocked( + reconcileRequest, mSettings.mKeySetManagerService); } catch (ReconcileFailure e) { for (InstallRequest request : requests) { - // TODO(b/109941548): add more concrete failure reasons request.installResult.setError("Reconciliation failed...", e); - // TODO: return any used system resources } return; } finally { @@ -15746,10 +15962,8 @@ public class PackageManagerService extends IPackageManager.Stub Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages"); commitRequest = new CommitRequest(reconciledPackages, sUserManager.getUserIds()); - if (!commitPackagesLocked(commitRequest)) { - cleanUpCommitFailuresLocked(commitRequest); - return; - } + commitPackagesLocked(commitRequest); + success = true; } finally { for (PrepareResult result : prepareResults.values()) { if (result.freezer != null) { @@ -15761,6 +15975,11 @@ public class PackageManagerService extends IPackageManager.Stub } executePostCommitSteps(commitRequest); } finally { + if (!success) { + for (ScanResult result : preparedScans.values()) { + unprepareScanResultLocked(result); + } + } for (PrepareResult result : prepareResults.values()) { if (result.freezer != null) { result.freezer.close(); @@ -15847,133 +16066,6 @@ public class PackageManagerService extends IPackageManager.Stub // TODO: Layering violation BackgroundDexOptService.notifyPackageChanged(packageName); } - - } - - private void cleanUpCommitFailuresLocked(CommitRequest request) { - final Map<String, ReconciledPackage> reconciledPackages = request.reconciledPackages; - final int[] allUsers = request.mAllUsers; - for (ReconciledPackage reconciledPackage : reconciledPackages.values()) { - final String pkgName1 = reconciledPackage.pkgSetting.pkg.packageName; - if (reconciledPackage.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) { - reconciledPackage.installResult.setError( - PackageManager.INSTALL_FAILED_INTERNAL_ERROR, "Commit failed..."); - } - final PackageParser.Package oldPackage = - reconciledPackage.prepareResult.existingPackage; - final PackageParser.Package newPackage = reconciledPackage.pkgSetting.pkg; - if (reconciledPackage.prepareResult.system) { - // Re installation failed. Restore old information - // Remove new pkg information - if (newPackage != null) { - removeInstalledPackageLI(newPackage, true); - } - // Add back the old system package - PackageParser.Package restoredPkg = null; - try { - final List<ScanResult> restoreResults = scanPackageTracedLI(oldPackage, - reconciledPackage.prepareResult.parseFlags, SCAN_UPDATE_SIGNATURE, 0, - reconciledPackage.installArgs.user); - for (ScanResult result : restoreResults) { - // failures should have been caught earlier, but in case it wasn't, - // let's double check - if (!result.success) { - throw new PackageManagerException( - "Scan failed for " + result.request.pkg.packageName); - } - } - for (ScanResult result : restoreResults) { - try { - prepareScanResultLocked(result); - final Map<String, ReconciledPackage> reconcileResult = - reconcilePackagesLocked(new ReconcileRequest( - Collections.singletonMap(result.pkgSetting.name, - result), - mSharedLibraries, - mPackages - )); - commitReconciledScanResultLocked( - reconcileResult.get(result.pkgSetting.name)); - } catch (PackageManagerException e) { - unprepareScanResultLocked(result); - throw e; - } - } - restoredPkg = restoreResults.get(0).pkgSetting.pkg; - } catch (PackageManagerException e) { - Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); - } - synchronized (mPackages) { - final boolean disabledSystem; - // Remove existing system package - removePackageLI(reconciledPackage.scanResult.pkgSetting.pkg, true); - disabledSystem = disableSystemPackageLPw( - reconciledPackage.scanResult.pkgSetting.pkg, restoredPkg); - if (disabledSystem) { - enableSystemPackageLPw(restoredPkg); - } - // Ensure the installer package name up to date - setInstallerPackageNameLPw(reconciledPackage.scanResult.pkgSetting.pkg, - reconciledPackage.installArgs.installerPackageName); - // Update permissions for restored package - mPermissionManager.updatePermissions( - restoredPkg.packageName, restoredPkg, false, mPackages.values(), - mPermissionCallback); - mSettings.writeLPr(); - } - Slog.i(TAG, "Successfully restored package : " + restoredPkg.packageName - + " after failed upgrade"); - } else if (reconciledPackage.prepareResult.replace) { - if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName1); - - // Revert all internal state mutations and added folders for the failed install - boolean deletedPkg = deletePackageLIF(pkgName1, null, true, - allUsers, /*TODO: deleteFlags*/ 0, - reconciledPackage.installResult.removedInfo, true, null); - - // Restore the old package - if (deletedPkg) { - if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + oldPackage); - File restoreFile = new File(oldPackage.codePath); - // Parse old package - boolean oldExternal = isExternal(oldPackage); - int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY - | (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); - int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; - try { - scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, - /* origUpdateTime */ System.currentTimeMillis(), null); - } catch (PackageManagerException e) { - Slog.e(TAG, "Failed to restore package : " + pkgName1 - + " after failed upgrade: " - + e.getMessage()); - return; - } - - synchronized (mPackages) { - // Ensure the installer package name up to date - setInstallerPackageNameLPw(oldPackage, - reconciledPackage.installArgs.installerPackageName); - - // Update permissions for restored package - mPermissionManager.updatePermissions( - oldPackage.packageName, oldPackage, false, mPackages.values(), - mPermissionCallback); - - mSettings.writeLPr(); - } - - Slog.i(TAG, "Successfully restored package : " + pkgName1 - + " after failed upgrade"); - } - } else { - // Remove package from internal structures, but keep around any - // data that might have already existed - deletePackageLIF(pkgName1, UserHandle.ALL, false, null, - PackageManager.DELETE_KEEP_DATA, - reconciledPackage.installResult.removedInfo, true, null); - } - } } /** @@ -19629,6 +19721,17 @@ public class PackageManagerService extends IPackageManager.Stub return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); } + /** + * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing + * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}. + */ + public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo, + int userId) { + Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED) + .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo); + mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId)); + } + public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) { UserManagerService ums = UserManagerService.getInstance(); if (ums != null) { @@ -23489,6 +23592,11 @@ public class PackageManagerService extends IPackageManager.Stub return setting.getEnabled(userId); } } + + @Override + public void setEnableRollbackCode(int token, int enableRollbackCode) { + PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode); + } } @GuardedBy("mPackages") diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 357872ef3321..ac9c6ef57101 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -2300,6 +2300,9 @@ class PackageManagerShellCommand extends ShellCommand { case "--staged": sessionParams.setStaged(); break; + case "--enable-rollback": + sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK; + break; default: throw new IllegalArgumentException("Unknown option " + opt); } @@ -2833,6 +2836,7 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]"); pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]"); pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]"); + pw.println(" [--enable-rollback]"); pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [--apex]"); pw.println(" [PATH|-]"); pw.println(" Install an application. Must provide the apk data to install, either as a"); diff --git a/services/core/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java index 3214e8895fd5..c50bf59f0206 100644 --- a/services/core/java/com/android/server/pm/PackageVerificationState.java +++ b/services/core/java/com/android/server/pm/PackageVerificationState.java @@ -16,11 +16,11 @@ package com.android.server.pm; -import com.android.server.pm.PackageManagerService.InstallArgs; - import android.content.pm.PackageManager; import android.util.SparseBooleanArray; +import com.android.server.pm.PackageManagerService.InstallParams; + /** * Tracks the package verification state for a particular package. Each package * verification has a required verifier and zero or more sufficient verifiers. @@ -29,7 +29,7 @@ import android.util.SparseBooleanArray; * then package verification is considered complete. */ class PackageVerificationState { - private final InstallArgs mArgs; + private final InstallParams mParams; private final SparseBooleanArray mSufficientVerifierUids; @@ -53,15 +53,15 @@ class PackageVerificationState { * @param requiredVerifierUid user ID of required package verifier * @param args */ - public PackageVerificationState(int requiredVerifierUid, InstallArgs args) { + PackageVerificationState(int requiredVerifierUid, InstallParams params) { mRequiredVerifierUid = requiredVerifierUid; - mArgs = args; + mParams = params; mSufficientVerifierUids = new SparseBooleanArray(); mExtendedTimeout = false; } - public InstallArgs getInstallArgs() { - return mArgs; + InstallParams getInstallParams() { + return mParams; } /** @@ -69,7 +69,7 @@ class PackageVerificationState { * * @param uid user ID of sufficient verifier */ - public void addSufficientVerifier(int uid) { + void addSufficientVerifier(int uid) { mSufficientVerifierUids.put(uid, true); } @@ -80,7 +80,7 @@ class PackageVerificationState { * @param uid user ID of the verifying agent * @return {@code true} if the verifying agent actually exists in our list */ - public boolean setVerifierResponse(int uid, int code) { + boolean setVerifierResponse(int uid, int code) { if (uid == mRequiredVerifierUid) { mRequiredVerificationComplete = true; switch (code) { @@ -120,7 +120,7 @@ class PackageVerificationState { * * @return {@code true} when verification is considered complete */ - public boolean isVerificationComplete() { + boolean isVerificationComplete() { if (!mRequiredVerificationComplete) { return false; } @@ -138,7 +138,7 @@ class PackageVerificationState { * * @return {@code true} if installation should be allowed */ - public boolean isInstallAllowed() { + boolean isInstallAllowed() { if (!mRequiredVerificationPassed) { return false; } @@ -153,7 +153,7 @@ class PackageVerificationState { /** * Extend the timeout for this Package to be verified. */ - public void extendTimeout() { + void extendTimeout() { if (!mExtendedTimeout) { mExtendedTimeout = true; } @@ -164,7 +164,7 @@ class PackageVerificationState { * * @return {@code true} if a timeout was already extended. */ - public boolean timeoutExtended() { + boolean timeoutExtended() { return mExtendedTimeout; } } diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java new file mode 100644 index 000000000000..223f99e5c3f0 --- /dev/null +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -0,0 +1,90 @@ +/* + * 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.server.pm; + +import android.annotation.NonNull; +import android.content.pm.PackageInstaller; +import android.content.pm.ParceledListSlice; +import android.util.SparseArray; + +import com.android.internal.annotations.GuardedBy; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class handles staged install sessions, i.e. install sessions that require packages to + * be installed only after a reboot. + */ +public class StagingManager { + + private static final String TAG = "StagingManager"; + + private final PackageManagerService mPm; + + // STOPSHIP: This is a temporary mock implementation of staged sessions. This variable + // shouldn't be needed at all. + // TODO(b/118865310): Implement staged sessions logic. + @GuardedBy("mStagedSessions") + private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>(); + + StagingManager(PackageManagerService pm) { + mPm = pm; + } + + private void updateStoredSession(@NonNull PackageInstallerSession sessionInfo) { + synchronized (mStagedSessions) { + PackageInstallerSession storedSession = mStagedSessions.get(sessionInfo.sessionId); + if (storedSession == null) { + throw new IllegalStateException("Attempting to change state of a session not " + + "known to StagingManager"); + } + mStagedSessions.put(sessionInfo.sessionId, sessionInfo); + } + } + + ParceledListSlice<PackageInstaller.SessionInfo> getSessions() { + final List<PackageInstaller.SessionInfo> result = new ArrayList<>(); + synchronized (mStagedSessions) { + for (int i = 0; i < mStagedSessions.size(); i++) { + result.add(mStagedSessions.valueAt(i).generateInfo(false)); + } + } + return new ParceledListSlice<>(result); + } + + void commitSession(@NonNull PackageInstallerSession sessionInfo) { + updateStoredSession(sessionInfo); + // TODO(b/118865310): Dispatch the session to apexd/PackageManager for verification. For + // now we directly mark it as ready. + sessionInfo.setStagedSessionReady(); + mPm.sendSessionUpdatedBroadcast(sessionInfo.generateInfo(), sessionInfo.userId); + } + + void createSession(@NonNull PackageInstallerSession sessionInfo) { + synchronized (mStagedSessions) { + mStagedSessions.append(sessionInfo.sessionId, sessionInfo); + } + } + + void abortSession(@NonNull PackageInstallerSession sessionInfo) { + updateStoredSession(sessionInfo); + synchronized (mStagedSessions) { + mStagedSessions.remove(sessionInfo.sessionId); + } + } +} diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 25ef7675e2b9..e57d9d7ab61c 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -785,10 +785,10 @@ public class DexManager { * files that can be direclty mapped. */ private static void logIfPackageHasUncompressedCode(PackageParser.Package pkg) { - logIfApkHasUncompressedCode(pkg.baseCodePath); + auditUncompressedCodeInApk(pkg.baseCodePath); if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { for (int i = 0; i < pkg.splitCodePaths.length; i++) { - logIfApkHasUncompressedCode(pkg.splitCodePaths[i]); + auditUncompressedCodeInApk(pkg.splitCodePaths[i]); } } } @@ -797,34 +797,41 @@ public class DexManager { * Generates log if the archive located at {@code fileName} has uncompressed dex file and so * files that can be direclty mapped. */ - private static void logIfApkHasUncompressedCode(String fileName) { + public static boolean auditUncompressedCodeInApk(String fileName) { StrictJarFile jarFile = null; try { jarFile = new StrictJarFile(fileName, false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); Iterator<ZipEntry> it = jarFile.iterator(); + boolean allCorrect = true; while (it.hasNext()) { ZipEntry entry = it.next(); if (entry.getName().endsWith(".dex")) { if (entry.getMethod() != ZipEntry.STORED) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has compressed dex code " + entry.getName()); } else if ((entry.getDataOffset() & 0x3) != 0) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has unaligned dex code " + entry.getName()); } } else if (entry.getName().endsWith(".so")) { if (entry.getMethod() != ZipEntry.STORED) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has compressed native code " + entry.getName()); } else if ((entry.getDataOffset() & (0x1000 - 1)) != 0) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has unaligned native code " + entry.getName()); } } } + return allCorrect; } catch (IOException ignore) { Slog.wtf(TAG, "Error when parsing APK " + fileName); + return false; } finally { try { if (jarFile != null) { diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING new file mode 100644 index 000000000000..076c94c994a5 --- /dev/null +++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING @@ -0,0 +1,12 @@ +{ + "presubmit": [ + { + "name": "GtsPermissionTestCases", + "options": [ + { + "include-filter": "com.google.android.permission.gts.DefaultPermissionGrantPolicyTest" + } + ] + } + ] +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/rollback/PackageRollbackData.java b/services/core/java/com/android/server/rollback/PackageRollbackData.java new file mode 100644 index 000000000000..15d12427f8be --- /dev/null +++ b/services/core/java/com/android/server/rollback/PackageRollbackData.java @@ -0,0 +1,49 @@ +/* + * 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.server.rollback; + +import android.content.rollback.PackageRollbackInfo; + +import java.io.File; +import java.time.Instant; + +/** + * Information about a rollback available for a particular package. + * This is similar to {@link PackageRollbackInfo}, but extended with + * additional information for internal bookkeeping. + */ +class PackageRollbackData { + public final PackageRollbackInfo info; + + /** + * The directory where the apk backup is stored. + */ + public final File backupDir; + + /** + * The time when the upgrade occurred, for purposes of expiring + * rollback data. + */ + public final Instant timestamp; + + PackageRollbackData(PackageRollbackInfo info, + File backupDir, Instant timestamp) { + this.info = info; + this.backupDir = backupDir; + this.timestamp = timestamp; + } +} diff --git a/services/core/java/com/android/server/rollback/RollbackManagerService.java b/services/core/java/com/android/server/rollback/RollbackManagerService.java new file mode 100644 index 000000000000..5bf204088306 --- /dev/null +++ b/services/core/java/com/android/server/rollback/RollbackManagerService.java @@ -0,0 +1,846 @@ +/* + * 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.server.rollback; + +import android.app.AppOpsManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.IIntentReceiver; +import android.content.IIntentSender; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.IntentSender; +import android.content.pm.PackageInfo; +import android.content.pm.PackageInstaller; +import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; +import android.content.pm.PackageParser; +import android.content.pm.ParceledListSlice; +import android.content.pm.StringParceledListSlice; +import android.content.rollback.IRollbackManager; +import android.content.rollback.PackageRollbackInfo; +import android.content.rollback.RollbackInfo; +import android.net.Uri; +import android.os.Binder; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.os.SELinux; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; +import com.android.server.LocalServices; +import com.android.server.SystemService; +import com.android.server.pm.PackageManagerServiceUtils; + +import libcore.io.IoUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.time.Instant; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * Service that manages APK level rollbacks. + * + * TODO: Make RollbackManagerService extend SystemService and move the + * IRollbackManager.Stub implementation to a new private + * RollbackManagerServiceImpl class. + * + * @hide + */ +public class RollbackManagerService extends IRollbackManager.Stub { + + private static final String TAG = "RollbackManager"; + + // Rollbacks expire after 48 hours. + // TODO: How to test rollback expiration works properly? + private static final long ROLLBACK_LIFETIME_DURATION_MILLIS = 48 * 60 * 60 * 1000; + + // Lock used to synchronize accesses to in-memory rollback data + // structures. By convention, methods with the suffix "Locked" require + // mLock is held when they are called. + private final Object mLock = new Object(); + + // Package rollback data available to be used for rolling back a package. + // This list is null until the rollback data has been loaded. + @GuardedBy("mLock") + private List<PackageRollbackData> mAvailableRollbacks; + + // The list of recently executed rollbacks. + // This list is null until the rollback data has been loaded. + @GuardedBy("mLock") + private List<RollbackInfo> mRecentlyExecutedRollbacks; + + // Data for available rollbacks and recently executed rollbacks is + // persisted in storage. Assuming the rollback data directory is + // /data/rollback, we use the following directory structure + // to store this data: + // /data/rollback/ + // available/ + // com.package.A-XXX/ + // base.apk + // rollback.json + // com.package.B-YYY/ + // base.apk + // rollback.json + // recently_executed.json + // TODO: Use AtomicFile for rollback.json and recently_executed.json. + private final File mRollbackDataDir; + private final File mAvailableRollbacksDir; + private final File mRecentlyExecutedRollbacksFile; + + private final Context mContext; + private final HandlerThread mHandlerThread; + + RollbackManagerService(Context context) { + mContext = context; + mHandlerThread = new HandlerThread("RollbackManagerServiceHandler"); + mHandlerThread.start(); + + mRollbackDataDir = new File(Environment.getDataDirectory(), "rollback"); + mAvailableRollbacksDir = new File(mRollbackDataDir, "available"); + mRecentlyExecutedRollbacksFile = new File(mRollbackDataDir, "recently_executed.json"); + + // Kick off loading of the rollback data from strorage in a background + // thread. + // TODO: Consider loading the rollback data directly here instead, to + // avoid the need to call ensureRollbackDataLoaded every time before + // accessing the rollback data? + // TODO: Test that this kicks off initial scheduling of rollback + // expiration. + getHandler().post(() -> ensureRollbackDataLoaded()); + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_PACKAGE_REPLACED); + filter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); + filter.addDataScheme("package"); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) { + String packageName = intent.getData().getSchemeSpecificPart(); + onPackageReplaced(packageName); + } + if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) { + String packageName = intent.getData().getSchemeSpecificPart(); + onPackageFullyRemoved(packageName); + } + } + }, filter, null, getHandler()); + + IntentFilter enableRollbackFilter = new IntentFilter(); + enableRollbackFilter.addAction(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK); + try { + enableRollbackFilter.addDataType("application/vnd.android.package-archive"); + } catch (IntentFilter.MalformedMimeTypeException e) { + Log.e(TAG, "addDataType", e); + } + + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_PACKAGE_ENABLE_ROLLBACK.equals(intent.getAction())) { + int token = intent.getIntExtra( + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, -1); + int installFlags = intent.getIntExtra( + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS, 0); + File newPackageCodePath = new File(intent.getData().getPath()); + + getHandler().post(() -> { + boolean success = enableRollback(installFlags, newPackageCodePath); + int ret = PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED; + if (!success) { + ret = PackageManagerInternal.ENABLE_ROLLBACK_FAILED; + } + + PackageManagerInternal pm = LocalServices.getService( + PackageManagerInternal.class); + pm.setEnableRollbackCode(token, ret); + }); + + // We're handling the ordered broadcast. Abort the + // broadcast because there is no need for it to go to + // anyone else. + abortBroadcast(); + } + } + }, enableRollbackFilter, null, getHandler()); + } + + @Override + public RollbackInfo getAvailableRollback(String packageName) { + PackageRollbackInfo.PackageVersion installedVersion = + getInstalledPackageVersion(packageName); + if (installedVersion == null) { + return null; + } + + synchronized (mLock) { + // TODO: Have ensureRollbackDataLoadedLocked return the list of + // available rollbacks, to hopefully avoid forgetting to call it? + ensureRollbackDataLoadedLocked(); + for (int i = 0; i < mAvailableRollbacks.size(); ++i) { + PackageRollbackData data = mAvailableRollbacks.get(i); + if (data.info.higherVersion.equals(installedVersion)) { + // TODO: For atomic installs, check all dependent packages + // for available rollbacks and include that info here. + return new RollbackInfo(data.info); + } + } + } + + return null; + } + + @Override + public StringParceledListSlice getPackagesWithAvailableRollbacks() { + // TODO: This may return packages whose rollback is out of date or + // expired. Presumably that's okay because the package rollback could + // be expired anyway between when the caller calls this method and + // when the caller calls getAvailableRollback for more details. + final Set<String> packageNames = new HashSet<>(); + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + for (int i = 0; i < mAvailableRollbacks.size(); ++i) { + PackageRollbackData data = mAvailableRollbacks.get(i); + packageNames.add(data.info.packageName); + } + } + return new StringParceledListSlice(new ArrayList<>(packageNames)); + } + + @Override + public ParceledListSlice<RollbackInfo> getRecentlyExecutedRollbacks() { + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + List<RollbackInfo> rollbacks = new ArrayList<>(mRecentlyExecutedRollbacks); + return new ParceledListSlice<>(rollbacks); + } + } + + @Override + public void executeRollback(RollbackInfo rollback, String callerPackageName, + IntentSender statusReceiver) { + final int callingUid = Binder.getCallingUid(); + if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) { + AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); + appOps.checkPackage(callingUid, callerPackageName); + } + + getHandler().post(() -> + executeRollbackInternal(rollback, callerPackageName, statusReceiver)); + } + + /** + * Performs the actual work to execute a rollback. + * The work is done on the current thread. This may be a long running + * operation. + */ + private void executeRollbackInternal(RollbackInfo rollback, + String callerPackageName, IntentSender statusReceiver) { + String packageName = rollback.targetPackage.packageName; + Log.i(TAG, "Initiating rollback of " + packageName); + + PackageRollbackInfo.PackageVersion installedVersion = + getInstalledPackageVersion(packageName); + if (installedVersion == null) { + // TODO: Test this case + sendFailure(statusReceiver, "Target package to roll back is not installed"); + return; + } + + if (!rollback.targetPackage.higherVersion.equals(installedVersion)) { + // TODO: Test this case + sendFailure(statusReceiver, "Target package version to roll back not installed."); + return; + } + + // TODO: We assume that between now and the time we commit the + // downgrade install, the currently installed package version does not + // change. This is not safe to assume, particularly in the case of a + // rollback racing with a roll-forward fix of a buggy package. + // Figure out how to ensure we don't commit the rollback if + // roll forward happens at the same time. + PackageRollbackData data = null; + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + for (int i = 0; i < mAvailableRollbacks.size(); ++i) { + PackageRollbackData available = mAvailableRollbacks.get(i); + // TODO: Check if available.info.lowerVersion matches + // rollback.targetPackage.lowerVersion? + if (available.info.higherVersion.equals(installedVersion)) { + data = available; + break; + } + } + } + + if (data == null) { + sendFailure(statusReceiver, "Rollback not available"); + return; + } + + // Get a context for the caller to use to install the downgraded + // version of the package. + Context context = null; + try { + context = mContext.createPackageContext(callerPackageName, 0); + } catch (PackageManager.NameNotFoundException e) { + sendFailure(statusReceiver, "Invalid callerPackageName"); + return; + } + + PackageManager pm = context.getPackageManager(); + try { + PackageInstaller.Session session = null; + + PackageInstaller packageInstaller = pm.getPackageInstaller(); + PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( + PackageInstaller.SessionParams.MODE_FULL_INSTALL); + params.setAllowDowngrade(true); + int sessionId = packageInstaller.createSession(params); + session = packageInstaller.openSession(sessionId); + + // TODO: Will it always be called "base.apk"? What about splits? + File baseApk = new File(data.backupDir, "base.apk"); + try (ParcelFileDescriptor fd = ParcelFileDescriptor.open(baseApk, + ParcelFileDescriptor.MODE_READ_ONLY)) { + final long token = Binder.clearCallingIdentity(); + try { + session.write("base.apk", 0, baseApk.length(), fd); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + final LocalIntentReceiver receiver = new LocalIntentReceiver(); + session.commit(receiver.getIntentSender()); + + Intent result = receiver.getResult(); + int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_FAILURE); + if (status != PackageInstaller.STATUS_SUCCESS) { + sendFailure(statusReceiver, "Rollback downgrade install failed: " + + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); + return; + } + + addRecentlyExecutedRollback(rollback); + sendSuccess(statusReceiver); + + // TODO: Restrict permissions for who can listen for this + // broadcast? + Intent broadcast = new Intent(Intent.ACTION_PACKAGE_ROLLBACK_EXECUTED, + Uri.fromParts("package", packageName, null)); + + // TODO: This call emits the warning "Calling a method in the + // system process without a qualified user". Fix that. + mContext.sendBroadcast(broadcast); + } catch (IOException e) { + Log.e(TAG, "Unable to roll back " + packageName, e); + sendFailure(statusReceiver, "IOException: " + e.toString()); + return; + } + } + + @Override + public void reloadPersistedData() { + synchronized (mLock) { + mAvailableRollbacks = null; + mRecentlyExecutedRollbacks = null; + } + getHandler().post(() -> ensureRollbackDataLoaded()); + } + + @Override + public void expireRollbackForPackage(String packageName) { + // TODO: Should this take a package version number in addition to + // package name? For now, just remove all rollbacks matching the + // package name. This method is only currently used to facilitate + // testing anyway. + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + Iterator<PackageRollbackData> iter = mAvailableRollbacks.iterator(); + while (iter.hasNext()) { + PackageRollbackData data = iter.next(); + if (data.info.packageName.equals(packageName)) { + iter.remove(); + removeFile(data.backupDir); + } + } + } + } + + /** + * Load rollback data from storage if it has not already been loaded. + * After calling this funciton, mAvailableRollbacks and + * mRecentlyExecutedRollbacks will be non-null. + */ + private void ensureRollbackDataLoaded() { + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + } + } + + /** + * Load rollback data from storage if it has not already been loaded. + * After calling this function, mAvailableRollbacks and + * mRecentlyExecutedRollbacks will be non-null. + */ + @GuardedBy("mLock") + private void ensureRollbackDataLoadedLocked() { + if (mAvailableRollbacks == null) { + loadRollbackDataLocked(); + } + } + + /** + * Load rollback data from storage. + * Note: We do potentially heavy IO here while holding mLock, because we + * have to have the rollback data loaded before we can do anything else + * meaningful. + */ + @GuardedBy("mLock") + private void loadRollbackDataLocked() { + mAvailableRollbacksDir.mkdirs(); + mAvailableRollbacks = new ArrayList<>(); + for (File rollbackDir : mAvailableRollbacksDir.listFiles()) { + if (rollbackDir.isDirectory()) { + // TODO: How to detect and clean up an invalid rollback + // directory? We don't know if it's invalid because something + // went wrong, or if it's only temporarily invalid because + // it's in the process of being created. + try { + File jsonFile = new File(rollbackDir, "rollback.json"); + String jsonString = IoUtils.readFileAsString(jsonFile.getAbsolutePath()); + JSONObject jsonObject = new JSONObject(jsonString); + String packageName = jsonObject.getString("packageName"); + long higherVersionCode = jsonObject.getLong("higherVersionCode"); + long lowerVersionCode = jsonObject.getLong("lowerVersionCode"); + Instant timestamp = Instant.parse(jsonObject.getString("timestamp")); + PackageRollbackData data = new PackageRollbackData( + new PackageRollbackInfo(packageName, + new PackageRollbackInfo.PackageVersion(higherVersionCode), + new PackageRollbackInfo.PackageVersion(lowerVersionCode)), + rollbackDir, timestamp); + mAvailableRollbacks.add(data); + } catch (IOException | JSONException | DateTimeParseException e) { + Log.e(TAG, "Unable to read rollback data at " + rollbackDir, e); + } + } + } + + mRecentlyExecutedRollbacks = new ArrayList<>(); + if (mRecentlyExecutedRollbacksFile.exists()) { + try { + // TODO: How to cope with changes to the format of this file from + // when RollbackStore is updated in the future? + String jsonString = IoUtils.readFileAsString( + mRecentlyExecutedRollbacksFile.getAbsolutePath()); + JSONObject object = new JSONObject(jsonString); + JSONArray array = object.getJSONArray("recentlyExecuted"); + for (int i = 0; i < array.length(); ++i) { + JSONObject element = array.getJSONObject(i); + String packageName = element.getString("packageName"); + long higherVersionCode = element.getLong("higherVersionCode"); + long lowerVersionCode = element.getLong("lowerVersionCode"); + PackageRollbackInfo target = new PackageRollbackInfo(packageName, + new PackageRollbackInfo.PackageVersion(higherVersionCode), + new PackageRollbackInfo.PackageVersion(lowerVersionCode)); + RollbackInfo rollback = new RollbackInfo(target); + mRecentlyExecutedRollbacks.add(rollback); + } + } catch (IOException | JSONException e) { + // TODO: What to do here? Surely we shouldn't just forget about + // everything after the point of exception? + Log.e(TAG, "Failed to read recently executed rollbacks", e); + } + } + + scheduleExpiration(0); + } + + /** + * Called when a package has been replaced with a different version. + * Removes all backups for the package not matching the currently + * installed package version. + */ + private void onPackageReplaced(String packageName) { + // TODO: Could this end up incorrectly deleting a rollback for a + // package that is about to be installed? + PackageRollbackInfo.PackageVersion installedVersion = + getInstalledPackageVersion(packageName); + + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + Iterator<PackageRollbackData> iter = mAvailableRollbacks.iterator(); + while (iter.hasNext()) { + PackageRollbackData data = iter.next(); + if (data.info.packageName.equals(packageName) + && !data.info.higherVersion.equals(installedVersion)) { + iter.remove(); + removeFile(data.backupDir); + } + } + } + } + + /** + * Called when a package has been completely removed from the device. + * Removes all backups and rollback history for the given package. + */ + private void onPackageFullyRemoved(String packageName) { + expireRollbackForPackage(packageName); + + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + Iterator<RollbackInfo> iter = mRecentlyExecutedRollbacks.iterator(); + boolean changed = false; + while (iter.hasNext()) { + RollbackInfo rollback = iter.next(); + if (packageName.equals(rollback.targetPackage.packageName)) { + iter.remove(); + changed = true; + } + } + + if (changed) { + saveRecentlyExecutedRollbacksLocked(); + } + } + } + + /** + * Write the list of recently executed rollbacks to storage. + * Note: This happens while mLock is held, which should be okay because we + * expect executed rollbacks to be modified only in exceptional cases. + */ + @GuardedBy("mLock") + private void saveRecentlyExecutedRollbacksLocked() { + try { + JSONObject json = new JSONObject(); + JSONArray array = new JSONArray(); + json.put("recentlyExecuted", array); + + for (int i = 0; i < mRecentlyExecutedRollbacks.size(); ++i) { + RollbackInfo rollback = mRecentlyExecutedRollbacks.get(i); + JSONObject element = new JSONObject(); + element.put("packageName", rollback.targetPackage.packageName); + element.put("higherVersionCode", rollback.targetPackage.higherVersion.versionCode); + element.put("lowerVersionCode", rollback.targetPackage.lowerVersion.versionCode); + array.put(element); + } + + PrintWriter pw = new PrintWriter(mRecentlyExecutedRollbacksFile); + pw.println(json.toString()); + pw.close(); + } catch (IOException | JSONException e) { + // TODO: What to do here? + Log.e(TAG, "Failed to save recently executed rollbacks", e); + } + } + + /** + * Records that the given package has been recently rolled back. + */ + private void addRecentlyExecutedRollback(RollbackInfo rollback) { + // TODO: if the list of rollbacks gets too big, trim it to only those + // that are necessary to keep track of. + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + mRecentlyExecutedRollbacks.add(rollback); + saveRecentlyExecutedRollbacksLocked(); + } + } + + /** + * Notifies an IntentSender of failure. + * + * @param statusReceiver where to send the failure + * @param message the failure message. + */ + private void sendFailure(IntentSender statusReceiver, String message) { + Log.e(TAG, message); + try { + // TODO: More context on which rollback failed? + // TODO: More refined failure code? + final Intent fillIn = new Intent(); + fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); + fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, message); + statusReceiver.sendIntent(mContext, 0, fillIn, null, null); + } catch (IntentSender.SendIntentException e) { + // Nowhere to send the result back to, so don't bother. + } + } + + /** + * Notifies an IntentSender of success. + */ + private void sendSuccess(IntentSender statusReceiver) { + try { + final Intent fillIn = new Intent(); + fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_SUCCESS); + statusReceiver.sendIntent(mContext, 0, fillIn, null, null); + } catch (IntentSender.SendIntentException e) { + // Nowhere to send the result back to, so don't bother. + } + } + + // Check to see if anything needs expiration, and if so, expire it. + // Schedules future expiration as appropriate. + // TODO: Handle cases where the user changes time on the device. + private void runExpiration() { + Instant now = Instant.now(); + Instant oldest = null; + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + + Iterator<PackageRollbackData> iter = mAvailableRollbacks.iterator(); + while (iter.hasNext()) { + PackageRollbackData data = iter.next(); + if (!now.isBefore(data.timestamp.plusMillis(ROLLBACK_LIFETIME_DURATION_MILLIS))) { + iter.remove(); + removeFile(data.backupDir); + } else if (oldest == null || oldest.isAfter(data.timestamp)) { + oldest = data.timestamp; + } + } + } + + if (oldest != null) { + scheduleExpiration(now.until(oldest.plusMillis(ROLLBACK_LIFETIME_DURATION_MILLIS), + ChronoUnit.MILLIS)); + } + } + + /** + * Schedules an expiration check to be run after the given duration in + * milliseconds has gone by. + */ + private void scheduleExpiration(long duration) { + getHandler().postDelayed(() -> runExpiration(), duration); + } + + /** + * Gets the RollbackManagerService's handler. + * To allow PackageManagerService to call into RollbackManagerService + * without fear of blocking the PackageManagerService thread. + */ + public Handler getHandler() { + return mHandlerThread.getThreadHandler(); + } + + /** + * Called via broadcast by the package manager when a package is being + * staged for install with rollback enabled. Called before the package has + * been installed. + * + * @param id the id of the enable rollback request + * @param installFlags information about what is being installed. + * @param newPackageCodePath path to the package about to be installed. + * @return true if enabling the rollback succeeds, false otherwise. + */ + private boolean enableRollback(int installFlags, File newPackageCodePath) { + if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { + Log.e(TAG, "Rollbacks not supported for instant app install"); + return false; + } + if ((installFlags & PackageManager.INSTALL_APEX) != 0) { + Log.e(TAG, "Rollbacks not supported for apex install"); + return false; + } + + // Get information about the package to be installed. + PackageParser.PackageLite newPackage = null; + try { + newPackage = PackageParser.parsePackageLite(newPackageCodePath, 0); + } catch (PackageParser.PackageParserException e) { + Log.e(TAG, "Unable to parse new package", e); + return false; + } + + String packageName = newPackage.packageName; + Log.i(TAG, "Enabling rollback for install of " + packageName); + + PackageRollbackInfo.PackageVersion newVersion = + new PackageRollbackInfo.PackageVersion(newPackage.versionCode); + + // Get information about the currently installed package. + PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class); + PackageParser.Package installedPackage = pm.getPackage(packageName); + if (installedPackage == null) { + // TODO: Support rolling back fresh package installs rather than + // fail here. Test this case. + Log.e(TAG, packageName + " is not installed"); + return false; + } + PackageRollbackInfo.PackageVersion installedVersion = + new PackageRollbackInfo.PackageVersion(installedPackage.getLongVersionCode()); + + File backupDir; + try { + backupDir = Files.createTempDirectory( + mAvailableRollbacksDir.toPath(), packageName + "-").toFile(); + } catch (IOException e) { + Log.e(TAG, "Unable to create rollback for " + packageName, e); + return false; + } + + // TODO: Should the timestamp be for when we commit the install, not + // when we create the pending one? + Instant timestamp = Instant.now(); + try { + JSONObject json = new JSONObject(); + json.put("packageName", packageName); + json.put("higherVersionCode", newVersion.versionCode); + json.put("lowerVersionCode", installedVersion.versionCode); + json.put("timestamp", timestamp.toString()); + + File jsonFile = new File(backupDir, "rollback.json"); + PrintWriter pw = new PrintWriter(jsonFile); + pw.println(json.toString()); + pw.close(); + } catch (IOException | JSONException e) { + Log.e(TAG, "Unable to create rollback for " + packageName, e); + removeFile(backupDir); + return false; + } + + // TODO: Copy by hard link instead to save on cpu and storage space? + int status = PackageManagerServiceUtils.copyPackage(installedPackage.codePath, backupDir); + if (status != PackageManager.INSTALL_SUCCEEDED) { + Log.e(TAG, "Unable to copy package for rollback for " + packageName); + removeFile(backupDir); + return false; + } + + PackageRollbackData data = new PackageRollbackData( + new PackageRollbackInfo(packageName, newVersion, installedVersion), + backupDir, timestamp); + + synchronized (mLock) { + ensureRollbackDataLoadedLocked(); + mAvailableRollbacks.add(data); + } + + return true; + } + + // TODO: Don't copy this from PackageManagerShellCommand like this? + private static class LocalIntentReceiver { + private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>(); + + private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { + @Override + public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, + IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { + try { + mResult.offer(intent, 5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }; + + public IntentSender getIntentSender() { + return new IntentSender((IIntentSender) mLocalSender); + } + + public Intent getResult() { + try { + return mResult.take(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + /** + * Deletes a file completely. + * If the file is a directory, its contents are deleted as well. + * Has no effect if the directory does not exist. + */ + private void removeFile(File file) { + if (file.isDirectory()) { + for (File child : file.listFiles()) { + removeFile(child); + } + } + if (file.exists()) { + file.delete(); + } + } + + /** + * Gets the version of the package currently installed. + * Returns null if the package is not currently installed. + */ + private PackageRollbackInfo.PackageVersion getInstalledPackageVersion(String packageName) { + PackageManager pm = mContext.getPackageManager(); + PackageInfo pkgInfo = null; + try { + pkgInfo = pm.getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + return null; + } + + return new PackageRollbackInfo.PackageVersion(pkgInfo.getLongVersionCode()); + } + + /** + * Manages the lifecycle of RollbackManagerService within System Server. + */ + public static class Lifecycle extends SystemService { + private RollbackManagerService mService; + + public Lifecycle(Context context) { + super(context); + } + + @Override + public void onStart() { + mService = new RollbackManagerService(getContext()); + + // TODO: Set up sepolicy to allow publishing the service. + if (SELinux.isSELinuxEnforced()) { + Log.w(TAG, "RollbackManager disabled pending selinux policy updates"); + } else { + publishBinderService(Context.ROLLBACK_SERVICE, mService); + } + } + } +} diff --git a/services/core/java/com/android/server/security/VerityUtils.java b/services/core/java/com/android/server/security/VerityUtils.java index 514dfed75843..667d21dc59a0 100644 --- a/services/core/java/com/android/server/security/VerityUtils.java +++ b/services/core/java/com/android/server/security/VerityUtils.java @@ -16,13 +16,11 @@ package com.android.server.security; -import static android.system.OsConstants.PROT_READ; -import static android.system.OsConstants.PROT_WRITE; - import android.annotation.NonNull; import android.os.SharedMemory; import android.system.ErrnoException; import android.system.Os; +import android.system.OsConstants; import android.util.Pair; import android.util.Slog; import android.util.apk.ApkSignatureVerifier; @@ -56,6 +54,21 @@ abstract public class VerityUtils { private static final boolean DEBUG = false; + /** Returns whether the file has fs-verity enabled. */ + public static boolean hasFsverity(@NonNull String filePath) { + // NB: only measure but not check the actual measurement here. As long as this succeeds, + // the file is on readable if the measurement can be verified against a trusted key, and + // this is good enough for installed apps. + int errno = measureFsverityNative(filePath); + if (errno != 0) { + if (errno != OsConstants.ENODATA) { + Slog.e(TAG, "Failed to measure fs-verity, errno " + errno + ": " + filePath); + } + return false; + } + return true; + } + /** * Generates Merkle tree and fs-verity metadata. * @@ -213,6 +226,7 @@ abstract public class VerityUtils { return md.digest(); } + private static native int measureFsverityNative(@NonNull String filePath); private static native byte[] constructFsveritySignedDataNative(@NonNull byte[] measurement); private static native byte[] constructFsverityDescriptorNative(long fileSize); private static native byte[] constructFsverityExtensionNative(short extensionId, @@ -249,7 +263,7 @@ abstract public class VerityUtils { if (shm == null) { throw new IllegalStateException("Failed to generate verity tree into shared memory"); } - if (!shm.setProtect(PROT_READ)) { + if (!shm.setProtect(OsConstants.PROT_READ)) { throw new SecurityException("Failed to set up shared memory correctly"); } return Pair.create(shm, contentSize); @@ -323,7 +337,7 @@ abstract public class VerityUtils { throw new IllegalStateException("Multiple instantiation from this factory"); } mShm = SharedMemory.create("apkverity", capacity); - if (!mShm.setProtect(PROT_READ | PROT_WRITE)) { + if (!mShm.setProtect(OsConstants.PROT_READ | OsConstants.PROT_WRITE)) { throw new SecurityException("Failed to set protection"); } mBuffer = mShm.mapReadWrite(); diff --git a/services/core/java/com/android/server/slice/SliceClientPermissions.java b/services/core/java/com/android/server/slice/SliceClientPermissions.java index e461e0d43735..ab94a59c4d9c 100644 --- a/services/core/java/com/android/server/slice/SliceClientPermissions.java +++ b/services/core/java/com/android/server/slice/SliceClientPermissions.java @@ -282,9 +282,12 @@ public class SliceClientPermissions implements DirtyTracker, Persistable { public synchronized void writeTo(XmlSerializer out) throws IOException { final int N = mPaths.size(); for (int i = 0; i < N; i++) { - out.startTag(NAMESPACE, TAG_PATH); - out.text(encodeSegments(mPaths.valueAt(i))); - out.endTag(NAMESPACE, TAG_PATH); + final String[] segments = mPaths.valueAt(i); + if (segments != null) { + out.startTag(NAMESPACE, TAG_PATH); + out.text(encodeSegments(segments)); + out.endTag(NAMESPACE, TAG_PATH); + } } } diff --git a/services/core/java/com/android/server/slice/SlicePermissionManager.java b/services/core/java/com/android/server/slice/SlicePermissionManager.java index 780bc962afba..315d5e39c94b 100644 --- a/services/core/java/com/android/server/slice/SlicePermissionManager.java +++ b/services/core/java/com/android/server/slice/SlicePermissionManager.java @@ -315,7 +315,8 @@ public class SlicePermissionManager implements DirtyTracker { return new AtomicFile(new File(mSliceDir, fileName)); } - private void handlePersist() { + @VisibleForTesting + void handlePersist() { synchronized (this) { for (Persistable persistable : mDirty) { AtomicFile file = getFile(persistable.getFileName()); @@ -335,7 +336,7 @@ public class SlicePermissionManager implements DirtyTracker { out.flush(); file.finishWrite(stream); - } catch (IOException | XmlPullParserException e) { + } catch (IOException | XmlPullParserException | RuntimeException e) { Slog.w(TAG, "Failed to save access file, restoring backup", e); file.failWrite(stream); } @@ -344,6 +345,12 @@ public class SlicePermissionManager implements DirtyTracker { } } + // use addPersistableDirty(); this is just for tests + @VisibleForTesting + void addDirtyImmediate(Persistable obj) { + mDirty.add(obj); + } + private void handleRemove(PkgUser pkgUser) { getFile(SliceClientPermissions.getFileName(pkgUser)).delete(); getFile(SliceProviderPermissions.getFileName(pkgUser)).delete(); diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 4ec8b87be3ac..30aa5280eac6 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -1563,11 +1563,16 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { return mBatteryStatsHelper; } + private long milliAmpHrsToNanoAmpSecs(double mAh) { + final long MILLI_AMP_HR_TO_NANO_AMP_SECS = 1_000_000L * 3600L; + return (long) (mAh * MILLI_AMP_HR_TO_NANO_AMP_SECS + 0.5); + } + private void pullDeviceCalculatedPowerUse(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) { BatteryStatsHelper bsHelper = getBatteryStatsHelper(); StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); - e.writeFloat((float) bsHelper.getComputedPower()); + e.writeLong(milliAmpHrsToNanoAmpSecs(bsHelper.getComputedPower())); pulledData.add(e); } @@ -1583,7 +1588,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(bs.uidObj.getUid()); - e.writeFloat((float) bs.totalPowerMah); + e.writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah)); pulledData.add(e); } } @@ -1603,7 +1608,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(bs.drainType.ordinal()); - e.writeFloat((float) bs.totalPowerMah); + e.writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah)); pulledData.add(e); } } diff --git a/services/core/java/com/android/server/textservices/TextServicesManagerInternal.java b/services/core/java/com/android/server/textservices/TextServicesManagerInternal.java new file mode 100644 index 000000000000..56bcdd9ec146 --- /dev/null +++ b/services/core/java/com/android/server/textservices/TextServicesManagerInternal.java @@ -0,0 +1,63 @@ +/* + * 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.server.textservices; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.view.textservice.SpellCheckerInfo; + +import com.android.server.LocalServices; + +/** + * Local interface of {@link TextServicesManagerService} inside system server process. + */ +public abstract class TextServicesManagerInternal { + /** + * Returns the list of installed input methods for the specified user. + * + * <p>CAVEAT: This method is not fully implemented yet. This may return an empty list if + * {@code userId} for a background user is specified. Check the implementation before starting + * this method.</p> + * + * @param userId The user ID to be queried. + * @return {@link SpellCheckerInfo} that is currently selected {@code userId}. + */ + @Nullable + public abstract SpellCheckerInfo getCurrentSpellCheckerForUser(@UserIdInt int userId); + + /** + * Fake implementation of {@link TextServicesManagerInternal}. All the methods do nothing. + */ + private static final TextServicesManagerInternal NOP = + new TextServicesManagerInternal() { + @Override + public SpellCheckerInfo getCurrentSpellCheckerForUser(@UserIdInt int userId) { + return null; + } + }; + + /** + * @return Global instance if exists. Otherwise, a dummy no-op instance. + */ + @NonNull + public static TextServicesManagerInternal get() { + final TextServicesManagerInternal instance = + LocalServices.getService(TextServicesManagerInternal.class); + return instance != null ? instance : NOP; + } +} diff --git a/services/core/java/com/android/server/textservices/TextServicesManagerService.java b/services/core/java/com/android/server/textservices/TextServicesManagerService.java index 97f238a97b8c..65d5b10590fa 100644 --- a/services/core/java/com/android/server/textservices/TextServicesManagerService.java +++ b/services/core/java/com/android/server/textservices/TextServicesManagerService.java @@ -56,6 +56,7 @@ import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ITextServicesManager; import com.android.internal.textservice.ITextServicesSessionListener; import com.android.internal.util.DumpUtils; +import com.android.server.LocalServices; import com.android.server.SystemService; import org.xmlpull.v1.XmlPullParserException; @@ -278,6 +279,14 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { @Override public void onStart() { + LocalServices.addService(TextServicesManagerInternal.class, + new TextServicesManagerInternal() { + @Override + public SpellCheckerInfo getCurrentSpellCheckerForUser( + @UserIdInt int userId) { + return mService.getCurrentSpellCheckerForUser(userId); + } + }); publishBinderService(Context.TEXT_SERVICES_MANAGER_SERVICE, mService); } @@ -493,6 +502,15 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { return spellCheckerList.get(0); } + @Nullable + private SpellCheckerInfo getCurrentSpellCheckerForUser(@UserIdInt int userId) { + synchronized (mLock) { + final int spellCheckerOwnerUserId = mSpellCheckerOwnerUserIdMap.get(userId); + final TextServicesData data = mUserData.get(spellCheckerOwnerUserId); + return data != null ? data.getCurrentSpellChecker() : null; + } + } + // TODO: Save SpellCheckerService by supported languages. Currently only one spell // checker is saved. @Override diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java index 973499f098b2..1f638c7f2e5d 100644 --- a/services/core/java/com/android/server/wm/ActivityDisplay.java +++ b/services/core/java/com/android/server/wm/ActivityDisplay.java @@ -37,6 +37,7 @@ import static com.android.server.am.ActivityDisplayProto.CONFIGURATION_CONTAINER import static com.android.server.am.ActivityDisplayProto.FOCUSED_STACK_ID; import static com.android.server.am.ActivityDisplayProto.ID; import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY; +import static com.android.server.am.ActivityDisplayProto.SINGLE_TASK_INSTANCE; import static com.android.server.am.ActivityDisplayProto.STACKS; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS; @@ -120,6 +121,9 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> */ private boolean mRemoved; + /** The display can only contain one task. */ + private boolean mSingleTaskInstance; + /** * A focusable stack that is purposely to be positioned at the top. Although the stack may not * have the topmost index, it is used as a preferred candidate to prevent being unable to resume @@ -244,6 +248,10 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> final ActivityStack prevFocusedStack = updateLastFocusedStackReason != null ? getFocusedStack() : null; final boolean wasContained = mStacks.remove(stack); + if (mSingleTaskInstance && getChildCount() > 0) { + throw new IllegalStateException( + "positionChildAt: Can only have one child on display=" + this); + } final int insertPosition = getTopInsertPosition(stack, position); mStacks.add(insertPosition, stack); @@ -403,6 +411,14 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> */ <T extends ActivityStack> T createStack(int windowingMode, int activityType, boolean onTop) { + if (mSingleTaskInstance && getChildCount() > 0) { + // Create stack on default display instead since this display can only contain 1 stack. + // TODO: Kinda a hack, but better that having the decision at each call point. Hoping + // this goes away once ActivityView is no longer using virtual displays. + return mRootActivityContainer.getDefaultDisplay().createStack( + windowingMode, activityType, onTop); + } + if (activityType == ACTIVITY_TYPE_UNDEFINED) { // Can't have an undefined stack type yet...so re-map to standard. Anyone that wants // anything else should be passing it in anyways... @@ -1337,8 +1353,31 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } } + void setDisplayToSingleTaskInstance() { + final int childCount = getChildCount(); + if (childCount > 1) { + throw new IllegalArgumentException("Display already has multiple stacks. display=" + + this); + } + if (childCount > 0) { + final ActivityStack stack = getChildAt(0); + if (stack.getChildCount() > 1) { + throw new IllegalArgumentException("Display stack already has multiple tasks." + + " display=" + this + " stack=" + stack); + } + } + + mSingleTaskInstance = true; + } + + /** Returns true if the display can only contain one task */ + boolean isSingleTaskInstance() { + return mSingleTaskInstance; + } + public void dump(PrintWriter pw, String prefix) { - pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size()); + pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size() + + (mSingleTaskInstance ? " mSingleTaskInstance" : "")); final String myPrefix = prefix + " "; if (mHomeStack != null) { pw.println(myPrefix + "mHomeStack=" + mHomeStack); @@ -1373,6 +1412,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> final long token = proto.start(fieldId); super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); proto.write(ID, mDisplayId); + proto.write(SINGLE_TASK_INSTANCE, mSingleTaskInstance); final ActivityStack focusedStack = getFocusedStack(); if (focusedStack != null) { proto.write(FOCUSED_STACK_ID, focusedStack.mStackId); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 4d8440a899a3..2cd0168aff42 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2486,36 +2486,20 @@ final class ActivityRecord extends ConfigurationContainer { } void setRequestedOrientation(int requestedOrientation) { - final int displayId = getDisplayId(); - final Configuration displayConfig = - mRootActivityContainer.getDisplayOverrideConfiguration(displayId); - - final Configuration config = setOrientation(requestedOrientation, - displayId, displayConfig, mayFreezeScreenLocked(app)); - if (config != null) { - frozenBeforeDestroy = true; - if (!mAtmService.updateDisplayOverrideConfigurationLocked(config, this, - false /* deferResume */, displayId)) { - mRootActivityContainer.resumeFocusedStacksTopActivities(); - } - } + setOrientation(requestedOrientation, mayFreezeScreenLocked(app)); mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged( task.taskId, requestedOrientation); } - Configuration setOrientation(int requestedOrientation, int displayId, - Configuration displayConfig, boolean freezeScreenIfNeeded) { + private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) { if (mAppWindowToken == null) { Slog.w(TAG_WM, "Attempted to set orientation of non-existing app token: " + appToken); - return null; + return; } - mAppWindowToken.setOrientation(requestedOrientation); - final IBinder binder = freezeScreenIfNeeded ? appToken.asBinder() : null; - return mAtmService.mWindowManager.updateOrientationFromAppTokens(displayConfig, binder, - displayId); + mAppWindowToken.setOrientation(requestedOrientation, binder, this); } int getOrientation() { diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 6755c7363ede..4581a0f9f350 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -66,6 +66,8 @@ import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; +import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; +import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; @@ -309,7 +311,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * The first entry in the list is the least recently used. * It contains HistoryRecord objects. */ - final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>(); + private final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>(); /** * When we are in the process of pausing an activity, before starting the @@ -1142,6 +1144,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } + /** @return true if the stack can only contain one task */ + boolean isSingleTaskInstance() { + final ActivityDisplay display = getDisplay(); + return display != null && display.isSingleTaskInstance(); + } + final void removeActivitiesFromLRUListLocked(TaskRecord task) { for (ActivityRecord r : task.mActivities) { mLRUActivities.remove(r); @@ -5153,6 +5161,47 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } + boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, + String dumpPackage, boolean needSep) { + pw.println(" Stack #" + mStackId + + ": type=" + activityTypeToString(getActivityType()) + + " mode=" + windowingModeToString(getWindowingMode())); + pw.println(" isSleeping=" + shouldSleepActivities()); + pw.println(" mBounds=" + getRequestedOverrideBounds()); + + boolean printed = dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, + needSep); + + printed |= dumpHistoryList(fd, pw, mLRUActivities, " ", "Run", false, + !dumpAll, false, dumpPackage, true, + " Running activities (most recent first):", null); + + needSep = printed; + boolean pr = printThisActivity(pw, mPausingActivity, dumpPackage, needSep, + " mPausingActivity: "); + if (pr) { + printed = true; + needSep = false; + } + pr = printThisActivity(pw, getResumedActivity(), dumpPackage, needSep, + " mResumedActivity: "); + if (pr) { + printed = true; + needSep = false; + } + if (dumpAll) { + pr = printThisActivity(pw, mLastPausedActivity, dumpPackage, needSep, + " mLastPausedActivity: "); + if (pr) { + printed = true; + needSep = true; + } + printed |= printThisActivity(pw, mLastNoHistoryActivity, dumpPackage, + needSep, " mLastNoHistoryActivity: "); + } + return printed; + } + boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage, boolean needSep) { @@ -5172,7 +5221,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai pw.println(prefix + "mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds); pw.println(prefix + "* " + task); task.dump(pw, prefix + " "); - ActivityStackSupervisor.dumpHistoryList(fd, pw, mTaskHistory.get(taskNdx).mActivities, + dumpHistoryList(fd, pw, mTaskHistory.get(taskNdx).mActivities, prefix, "Hist", true, !dumpAll, dumpClient, dumpPackage, false, null, task); } return true; @@ -5241,11 +5290,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}. */ void removeTask(TaskRecord task, String reason, int mode) { - // TODO(b/119259346): Move some logic below to TaskRecord. See bug for more context. - for (ActivityRecord record : task.mActivities) { - onActivityRemovedFromStack(record); - } - final boolean removed = mTaskHistory.remove(task); if (removed) { @@ -5255,25 +5299,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai removeActivitiesFromLRUListLocked(task); updateTaskMovement(task, true); - if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) { - // This task is going away, so save the last state if necessary. - task.saveLaunchingStateIfNeeded(); - - // TODO: VI what about activity? - final boolean isVoiceSession = task.voiceSession != null; - if (isVoiceSession) { - try { - task.voiceSession.taskFinished(task.intent, task.taskId); - } catch (RemoteException e) { - } - } - if (task.autoRemoveFromRecents() || isVoiceSession) { - // Task creator asked to remove this when done, or this task was a voice - // interaction, so it should not remain on the recent tasks list. - mStackSupervisor.mRecentTasks.remove(task); - } - - task.removeWindowContainer(); + if (mode == REMOVE_TASK_MODE_DESTROYING) { + task.cleanUpResourcesForDestroy(); } if (mTaskHistory.isEmpty()) { @@ -5348,6 +5375,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai String reason) { // TODO: Is this remove really needed? Need to look into the call path for the other addTask mTaskHistory.remove(task); + if (isSingleTaskInstance() && !mTaskHistory.isEmpty()) { + throw new IllegalStateException("Can only have one child on stack=" + this); + } + position = getAdjustedPositionForTask(task, position, null /* starting */); final boolean toTop = position >= mTaskHistory.size(); final ActivityStack prevStack = preAddTask(task, reason, toTop); diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index 904d9dd059c4..b4d5d9f6e5cd 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -355,7 +355,6 @@ public class ActivityStartController { ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, null, userId, ActivityStarter.computeResolveFilterUid( callingUid, realCallingUid, UserHandle.USER_NULL)); - // TODO: New, check if this is correct aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId); if (aInfo != null && diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index f662d0cc7f23..86c5d4d1726d 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -1426,6 +1426,42 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } /** + * Public API to check if the client is allowed to start an activity on specified display. + * + * If the target display is private or virtual, some restrictions will apply. + * + * @param displayId Target display id. + * @param intent Intent used to launch the activity. + * @param resolvedType The MIME type of the intent. + * @param userId The id of the user for whom the call is made. + * @return {@code true} if a call to start an activity on the target display should succeed and + * no {@link SecurityException} will be thrown, {@code false} otherwise. + */ + @Override + public final boolean isActivityStartAllowedOnDisplay(int displayId, Intent intent, + String resolvedType, int userId) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + final long origId = Binder.clearCallingIdentity(); + + try { + // Collect information about the target of the Intent. + ActivityInfo aInfo = mStackSupervisor.resolveActivity(intent, resolvedType, + 0 /* startFlags */, null /* profilerInfo */, userId, + ActivityStarter.computeResolveFilterUid(callingUid, callingUid, + UserHandle.USER_NULL)); + aInfo = mAmInternal.getActivityInfoForUser(aInfo, userId); + + synchronized (mGlobalLock) { + return mStackSupervisor.canPlaceEntityOnDisplay(displayId, callingPid, callingUid, + aInfo); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + /** * This is the internal entry point for handling Activity.finish(). * * @param token The Binder token referencing the Activity we want to finish. @@ -4533,6 +4569,26 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + /** + * Makes the display with the given id a single task instance display. I.e the display can only + * contain one task. + */ + @Override + public void setDisplayToSingleTaskInstance(int displayId) { + mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, + "setDisplayToSingleTaskInstance"); + final long origId = Binder.clearCallingIdentity(); + try { + final ActivityDisplay display = + mRootActivityContainer.getActivityDisplayOrCreate(displayId); + if (display != null) { + display.setDisplayToSingleTaskInstance(); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + void dumpLastANRLocked(PrintWriter pw) { pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)"); if (mLastANRState == null) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 1943efca8ad0..a5ceee268fa2 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -397,10 +397,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final Matrix mTmpMatrix = new Matrix(); private final Region mTmpRegion = new Region(); - /** Used for handing back size of display */ private final Rect mTmpBounds = new Rect(); + private final Configuration mTmpConfiguration = new Configuration(); + /** Remove this display when animation on it has completed. */ private boolean mDeferredRemoval; @@ -1156,6 +1157,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget(); } + @Override + boolean onDescendantOrientationChanged(IBinder freezeDisplayToken, + ConfigurationContainer requestingContainer) { + final Configuration config = updateOrientationFromAppTokens( + getRequestedOverrideConfiguration(), freezeDisplayToken, false); + // If display rotation class tells us that it doesn't consider app requested orientation, + // this display won't rotate just because of an app changes its requested orientation. Thus + // it indicates that this display chooses not to handle this request. + final boolean handled = getDisplayRotation().respectAppRequestedOrientation(); + if (config == null) { + return handled; + } + + if (handled && requestingContainer instanceof ActivityRecord) { + final ActivityRecord activityRecord = (ActivityRecord) requestingContainer; + final boolean kept = mWmService.mAtmService.updateDisplayOverrideConfigurationLocked( + config, activityRecord, false /* deferResume */, getDisplayId()); + activityRecord.frozenBeforeDestroy = true; + if (!kept) { + mWmService.mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities(); + } + } else { + // We have a new configuration to push so we need to update ATMS for now. + // TODO: Clean up display configuration push between ATMS and WMS after unification. + mWmService.mAtmService.updateDisplayOverrideConfigurationLocked( + config, null /* starting */, false /* deferResume */, getDisplayId()); + } + return handled; + } + /** * Determine the new desired orientation of this display. * @@ -1169,7 +1200,56 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return updateOrientationFromAppTokens(false /* forceUpdate */); } - boolean updateOrientationFromAppTokens(boolean forceUpdate) { + /** + * Update orientation of the target display, returning a non-null new Configuration if it has + * changed from the current orientation. If a non-null configuration is returned, someone must + * call {@link WindowManagerService#setNewDisplayOverrideConfiguration(Configuration, + * DisplayContent)} to tell the window manager it can unfreeze the screen. This will typically + * be done by calling {@link WindowManagerService#sendNewConfiguration(int)}. + */ + Configuration updateOrientationFromAppTokens(Configuration currentConfig, + IBinder freezeDisplayToken, boolean forceUpdate) { + if (!mDisplayReady) { + return null; + } + + Configuration config = null; + if (updateOrientationFromAppTokens(forceUpdate)) { + // If we changed the orientation but mOrientationChangeComplete is already true, + // we used seamless rotation, and we don't need to freeze the screen. + if (freezeDisplayToken != null && !mWmService.mRoot.mOrientationChangeComplete) { + final AppWindowToken atoken = getAppWindowToken(freezeDisplayToken); + if (atoken != null) { + atoken.startFreezingScreen(); + } + } + config = new Configuration(); + computeScreenConfiguration(config); + } else if (currentConfig != null) { + // No obvious action we need to take, but if our current state mismatches the + // activity manager's, update it, disregarding font scale, which should remain set + // to the value of the previous configuration. + // Here we're calling Configuration#unset() instead of setToDefaults() because we + // need to keep override configs clear of non-empty values (e.g. fontSize). + mTmpConfiguration.unset(); + mTmpConfiguration.updateFrom(currentConfig); + computeScreenConfiguration(mTmpConfiguration); + if (currentConfig.diff(mTmpConfiguration) != 0) { + mWaitingForConfig = true; + setLayoutNeeded(); + int[] anim = new int[2]; + getDisplayPolicy().selectRotationAnimationLw(anim); + + mWmService.startFreezingDisplayLocked(anim[0], anim[1], this); + config = new Configuration(mTmpConfiguration); + } + } + + return config; + } + + + private boolean updateOrientationFromAppTokens(boolean forceUpdate) { final int req = getOrientation(); if (req != mLastOrientation || forceUpdate) { mLastOrientation = req; diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 7aabc15d9860..bcc7be42333b 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -329,6 +329,15 @@ public class DisplayRotation { return mFixedToUserRotation; } + /** + * Returns {@code true} if this display rotation takes app requested orientation into + * consideration; {@code false} otherwise. For the time being the only case where this is {@code + * false} is when {@link #isFixedToUserRotation()} is {@code true}. + */ + boolean respectAppRequestedOrientation() { + return !mFixedToUserRotation; + } + public int getLandscapeRotation() { return mLandscapeRotation; } diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java index 45d77dee1851..5cfa7dec386e 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java +++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java @@ -326,15 +326,11 @@ class DisplayWindowSettings { void applySettingsToDisplayLocked(DisplayContent dc) { final DisplayInfo displayInfo = dc.getDisplayInfo(); - final Entry entry = getEntry(displayInfo); + final Entry entry = getOrCreateEntry(displayInfo); // Setting windowing mode first, because it may override overscan values later. dc.setWindowingMode(getWindowingModeLocked(entry, dc.getDisplayId())); - if (entry == null) { - return; - } - displayInfo.overscanLeft = entry.mOverscanLeft; displayInfo.overscanTop = entry.mOverscanTop; displayInfo.overscanRight = entry.mOverscanRight; diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 282838f7d58b..49a3186be9b4 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.graphics.Point; import android.graphics.Rect; import android.util.proto.ProtoOutputStream; +import android.view.InsetsState; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.InsetsSource; @@ -47,8 +48,18 @@ class InsetsSourceProvider { private WindowState mWin; private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider; + /** The visibility override from the current controlling window. */ + private boolean mClientVisible; + + /** + * Whether the window is available and considered visible as in {@link WindowState#isVisible}. + */ + private boolean mServerVisible; + + InsetsSourceProvider(InsetsSource source, InsetsStateController stateController, DisplayContent displayContent) { + mClientVisible = InsetsState.getDefaultVisibly(source.getType()); mSource = source; mDisplayContent = displayContent; mStateController = stateController; @@ -73,10 +84,9 @@ class InsetsSourceProvider { mWin = win; mFrameProvider = frameProvider; if (win == null) { - mSource.setVisible(false); + setServerVisible(false); mSource.setFrame(new Rect()); } else { - mSource.setVisible(true); mWin.setInsetProvider(this); } } @@ -96,7 +106,7 @@ class InsetsSourceProvider { mTmpRect.inset(mWin.mGivenContentInsets); } mSource.setFrame(mTmpRect); - mSource.setVisible(mWin.isVisible() && !mWin.mGivenInsetsPending); + setServerVisible(mWin.isVisible() && !mWin.mGivenInsetsPending); } @@ -113,6 +123,29 @@ class InsetsSourceProvider { false /* TODO hidden */); mControllingWin = target; mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash); + setClientVisible(InsetsState.getDefaultVisibly(mSource.getType())); + } + + boolean onInsetsModified(WindowState caller, InsetsSource modifiedSource) { + if (mControllingWin != caller || modifiedSource.isVisible() == mClientVisible) { + return false; + } + setClientVisible(modifiedSource.isVisible()); + return true; + } + + private void setClientVisible(boolean clientVisible) { + mClientVisible = clientVisible; + updateVisibility(); + } + + private void setServerVisible(boolean serverVisible) { + mServerVisible = serverVisible; + updateVisibility(); + } + + private void updateVisibility() { + mSource.setVisible(mServerVisible && mClientVisible); } InsetsSourceControl getControl() { @@ -125,6 +158,7 @@ class InsetsSourceProvider { // Cancelling the animation will invoke onAnimationCancelled, resetting all the fields. mWin.cancelAnimation(); } + setClientVisible(InsetsState.getDefaultVisibly(mSource.getType())); } private class ControlAdapter implements AnimationAdapter { diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index 592b7fba4bfd..8e119bb195d6 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -25,6 +25,7 @@ import android.annotation.Nullable; import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; +import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.ViewRootImpl; @@ -117,6 +118,21 @@ class InsetsStateController { } } + void onInsetsModified(WindowState windowState, InsetsState state) { + boolean changed = false; + for (int i = state.getSourcesCount() - 1; i >= 0; i--) { + final InsetsSource source = state.sourceAt(i); + final InsetsSourceProvider provider = mControllers.get(source.getType()); + if (provider == null) { + continue; + } + changed |= provider.onInsetsModified(windowState, source); + } + if (changed) { + notifyInsetsChanged(); + } + } + void onImeTargetChanged(@Nullable WindowState imeTarget) { onControlChanged(TYPE_IME, imeTarget); notifyPendingInsetsControlChanged(); diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index d0937e9fba10..f55c7c96e325 100644 --- a/services/core/java/com/android/server/wm/RootActivityContainer.java +++ b/services/core/java/com/android/server/wm/RootActivityContainer.java @@ -29,8 +29,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.app.WindowConfiguration.activityTypeToString; -import static android.app.WindowConfiguration.windowingModeToString; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; @@ -597,11 +595,15 @@ class RootActivityContainer extends ConfigurationContainer // Force-update the orientation from the WindowManager, since we need the true configuration // to send to the client now. - final Configuration config = mWindowManager.updateOrientationFromAppTokens( - getDisplayOverrideConfiguration(displayId), - starting != null && starting.mayFreezeScreenLocked(starting.app) - ? starting.appToken : null, - displayId, true /* forceUpdate */); + final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId); + Configuration config = null; + if (displayContent != null) { + config = displayContent.updateOrientationFromAppTokens( + getDisplayOverrideConfiguration(displayId), + starting != null && starting.mayFreezeScreenLocked(starting.app) + ? starting.appToken : null, + true /* forceUpdate */); + } if (starting != null && markFrozenIfConfigChanged && config != null) { starting.frozenBeforeDestroy = true; } @@ -911,6 +913,13 @@ class RootActivityContainer extends ConfigurationContainer + " to its current displayId=" + displayId); } + if (activityDisplay.isSingleTaskInstance() && activityDisplay.getChildCount() > 0) { + // We don't allow moving stacks to single instance display that already has a child. + Slog.e(TAG, "Can not move stack=" + stack + + " to single task instance display=" + activityDisplay); + return; + } + stack.reparent(activityDisplay, onTop, false /* displayRemoved */); // TODO(multi-display): resize stacks properly if moved from split-screen. } @@ -2297,42 +2306,7 @@ class RootActivityContainer extends ConfigurationContainer for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = display.getChildAt(stackNdx); pw.println(); - pw.println(" Stack #" + stack.mStackId - + ": type=" + activityTypeToString(stack.getActivityType()) - + " mode=" + windowingModeToString(stack.getWindowingMode())); - pw.println(" isSleeping=" + stack.shouldSleepActivities()); - pw.println(" mBounds=" + stack.getRequestedOverrideBounds()); - - printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, - needSep); - - printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, - !dumpAll, false, dumpPackage, true, - " Running activities (most recent first):", null); - - needSep = printed; - boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, - " mPausingActivity: "); - if (pr) { - printed = true; - needSep = false; - } - pr = printThisActivity(pw, stack.getResumedActivity(), dumpPackage, needSep, - " mResumedActivity: "); - if (pr) { - printed = true; - needSep = false; - } - if (dumpAll) { - pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, - " mLastPausedActivity: "); - if (pr) { - printed = true; - needSep = true; - } - printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, - needSep, " mLastNoHistoryActivity: "); - } + printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep); needSep = printed; } printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep, diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index dcade2f012db..4e70bbc277d8 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -198,7 +198,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> @Override void onChildPositionChanged() { - mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateInputWindows */); + mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, + !mWmService.mPerDisplayFocusEnabled /* updateInputWindows */); } DisplayContent getDisplayContent(int displayId) { diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 37b5a7c30218..d85fdb03e4a6 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -430,6 +430,18 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } } + @Override + public void insetsModified(IWindow window, InsetsState state) { + synchronized (mService.mWindowMap) { + final WindowState windowState = mService.windowForClientLocked(this, window, + false /* throwOnError */); + if (windowState != null) { + windowState.getDisplayContent().getInsetsStateController().onInsetsModified( + windowState, state); + } + } + } + void windowAddedLocked(String packageName) { mPackageName = packageName; mRelayoutTag = "relayoutWindow: " + mPackageName; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index b10fd31ba7ad..d334bd298ada 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -44,6 +44,7 @@ import android.app.ActivityManager.TaskDescription; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; +import android.os.IBinder; import android.util.EventLog; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -328,6 +329,23 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta return boundsChange; } + @Override + public boolean onDescendantOrientationChanged(IBinder freezeDisplayToken, + ConfigurationContainer requestingContainer) { + if (super.onDescendantOrientationChanged(freezeDisplayToken, requestingContainer)) { + return true; + } + + // No one in higher hierarchy handles this request, let's adjust our bounds to fulfill + // it if possible. + // TODO: Move to TaskRecord after unification is done. + if (mTaskRecord != null) { + mTaskRecord.onConfigurationChanged(mTaskRecord.getParent().getConfiguration()); + return true; + } + return false; + } + void resize(boolean relayout, boolean forced) { if (setBounds(getRequestedOverrideBounds(), forced) != BOUNDS_CHANGE_NONE && relayout) { getDisplayContent().layoutAndAssignWindowLayersIfNeeded(); diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java index 8c800097e49d..f1b0c0696353 100644 --- a/services/core/java/com/android/server/wm/TaskRecord.java +++ b/services/core/java/com/android/server/wm/TaskRecord.java @@ -481,6 +481,32 @@ class TaskRecord extends ConfigurationContainer { mTask = task; } + void cleanUpResourcesForDestroy() { + if (!mActivities.isEmpty()) { + return; + } + + // This task is going away, so save the last state if necessary. + saveLaunchingStateIfNeeded(); + + // TODO: VI what about activity? + final boolean isVoiceSession = voiceSession != null; + if (isVoiceSession) { + try { + voiceSession.taskFinished(intent, taskId); + } catch (RemoteException e) { + } + } + if (autoRemoveFromRecents() || isVoiceSession) { + // Task creator asked to remove this when done, or this task was a voice + // interaction, so it should not remain on the recent tasks list. + mService.mStackSupervisor.mRecentTasks.remove(this); + } + + removeWindowContainer(); + } + + @VisibleForTesting void removeWindowContainer() { mService.getLockTaskController().clearLockedTask(this); if (mTask == null) { diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 11d9ebb59db0..ee74bdfaa113 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -996,15 +996,20 @@ public class TaskStack extends WindowContainer<Task> implements * Adjusts the stack bounds if the IME is visible. * * @param imeWin The IME window. + * @param keepLastAmount Use {@code true} to keep the last adjusted amount from + * {@link DockedStackDividerController} for adjusting the stack bounds, + * Use {@code false} to reset adjusted amount as 0. + * @see #updateAdjustForIme(float, float, boolean) */ - void setAdjustedForIme(WindowState imeWin, boolean forceUpdate) { + void setAdjustedForIme(WindowState imeWin, boolean keepLastAmount) { mImeWin = imeWin; mImeGoingAway = false; - if (!mAdjustedForIme || forceUpdate) { + if (!mAdjustedForIme || keepLastAmount) { mAdjustedForIme = true; - mAdjustImeAmount = 0f; - mAdjustDividerAmount = 0f; - updateAdjustForIme(0f, 0f, true /* force */); + DockedStackDividerController controller = getDisplayContent().mDividerControllerLocked; + final float adjustImeAmount = keepLastAmount ? controller.mLastAnimationProgress : 0f; + final float adjustDividerAmount = keepLastAmount ? controller.mLastDividerProgress : 0f; + updateAdjustForIme(adjustImeAmount, adjustDividerAmount, true /* force */); } } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 651089d6ce10..32c5a3b8688e 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -31,10 +31,12 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.CallSuper; import android.annotation.IntDef; +import android.annotation.Nullable; import android.app.WindowConfiguration; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; +import android.os.IBinder; import android.util.Pools; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -698,8 +700,58 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } } + /** + * Called when this container or one of its descendants changed its requested orientation, and + * wants this container to handle it or pass it to its parent. + * + * @param freezeDisplayToken freeze this app window token if display needs to freeze + * @param requestingContainer the container which orientation request has changed + * @return {@code true} if handled; {@code false} otherwise. + */ + boolean onDescendantOrientationChanged(@Nullable IBinder freezeDisplayToken, + @Nullable ConfigurationContainer requestingContainer) { + final WindowContainer parent = getParent(); + if (parent == null) { + return false; + } + return parent.onDescendantOrientationChanged(freezeDisplayToken, + requestingContainer); + } + + /** + * Calls {@link #setOrientation(int, IBinder, ActivityRecord)} with {@code null} to the last 2 + * parameters. + * + * @param orientation the specified orientation. + */ void setOrientation(int orientation) { + setOrientation(orientation, null /* freezeDisplayToken */, + null /* ActivityRecord */); + } + + /** + * Sets the specified orientation of this container. It percolates this change upward along the + * hierarchy to let each level of the hierarchy a chance to respond to it. + * + * @param orientation the specified orientation. Needs to be one of {@link + * android.content.pm.ActivityInfo.ScreenOrientation}. + * @param freezeDisplayToken uses this token to freeze display if orientation change is not + * done. Display will not be frozen if this is {@code null}, which + * should only happen in tests. + * @param requestingContainer the container which orientation request has changed. Mostly used + * to ensure it gets correct configuration. + */ + void setOrientation(int orientation, @Nullable IBinder freezeDisplayToken, + @Nullable ConfigurationContainer requestingContainer) { + final boolean changed = mOrientation != orientation; mOrientation = orientation; + if (!changed) { + return; + } + final WindowContainer parent = getParent(); + if (parent != null) { + onDescendantOrientationChanged(freezeDisplayToken, requestingContainer); + } } int getOrientation() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index e3ced8350f0d..b6a4a51c41f2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2383,85 +2383,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - @Override - public Configuration updateOrientationFromAppTokens(Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId) { - return updateOrientationFromAppTokens(currentConfig, freezeThisOneIfNeeded, displayId, - false /* forceUpdate */); - } - - public Configuration updateOrientationFromAppTokens(Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) { - if (!checkCallingPermission(MANAGE_APP_TOKENS, "updateOrientationFromAppTokens()")) { - throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); - } - - final Configuration config; - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded, - displayId, forceUpdate); - } - } finally { - Binder.restoreCallingIdentity(ident); - } - - return config; - } - - /** - * Update orientation of the target display, returning a non-null new Configuration if it has - * changed from the current orientation. If a non-null configuration is returned, someone must - * call {@link #setNewDisplayOverrideConfiguration(Configuration, int)} to tell the window - * manager it can unfreeze the screen. This will typically be done by calling - * {@link #sendNewConfiguration(int)}. - * - * @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int) - */ - private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig, - IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) { - if (!mDisplayReady) { - return null; - } - Configuration config = null; - - final DisplayContent dc = mRoot.getDisplayContent(displayId); - if (dc != null && dc.updateOrientationFromAppTokens(forceUpdate)) { - // If we changed the orientation but mOrientationChangeComplete is already true, - // we used seamless rotation, and we don't need to freeze the screen. - if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) { - final AppWindowToken atoken = mRoot.getAppWindowToken(freezeThisOneIfNeeded); - if (atoken != null) { - atoken.startFreezingScreen(); - } - } - config = computeNewConfigurationLocked(displayId); - - } else if (currentConfig != null) { - // No obvious action we need to take, but if our current state mismatches the activity - // manager's, update it, disregarding font scale, which should remain set to the value - // of the previous configuration. - // Here we're calling Configuration#unset() instead of setToDefaults() because we need - // to keep override configs clear of non-empty values (e.g. fontSize). - mTempConfiguration.unset(); - mTempConfiguration.updateFrom(currentConfig); - final DisplayContent displayContent = mRoot.getDisplayContent(displayId); - displayContent.computeScreenConfiguration(mTempConfiguration); - if (currentConfig.diff(mTempConfiguration) != 0) { - displayContent.mWaitingForConfig = true; - displayContent.setLayoutNeeded(); - int anim[] = new int[2]; - displayContent.getDisplayPolicy().selectRotationAnimationLw(anim); - - startFreezingDisplayLocked(anim[0], anim[1], displayContent); - config = new Configuration(mTempConfiguration); - } - } - - return config; - } - void setNewDisplayOverrideConfiguration(Configuration overrideConfig, @NonNull DisplayContent dc) { if (dc.mWaitingForConfig) { diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 6d7219173b32..b4fe83704ff2 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -111,6 +111,7 @@ cc_defaults { "android.hardware.light@2.0", "android.hardware.power@1.0", "android.hardware.power@1.1", + "android.hardware.power.stats@1.0", "android.hardware.tetheroffload.config@1.0", "android.hardware.thermal@1.0", "android.hardware.tv.cec@1.0", diff --git a/services/core/jni/BroadcastRadio/NativeCallbackThread.h b/services/core/jni/BroadcastRadio/NativeCallbackThread.h index 53990be06535..0f62de9c39df 100644 --- a/services/core/jni/BroadcastRadio/NativeCallbackThread.h +++ b/services/core/jni/BroadcastRadio/NativeCallbackThread.h @@ -41,7 +41,7 @@ class NativeCallbackThread { DISALLOW_COPY_AND_ASSIGN(NativeCallbackThread); public: - NativeCallbackThread(JavaVM *vm); + explicit NativeCallbackThread(JavaVM *vm); virtual ~NativeCallbackThread(); void enqueue(const Task &task); diff --git a/services/core/jni/BroadcastRadio/Tuner.cpp b/services/core/jni/BroadcastRadio/Tuner.cpp index 9c2e1e59dd32..a2a7f7d9645d 100644 --- a/services/core/jni/BroadcastRadio/Tuner.cpp +++ b/services/core/jni/BroadcastRadio/Tuner.cpp @@ -73,7 +73,8 @@ class HalDeathRecipient : public hidl_death_recipient { wp<V1_1::ITunerCallback> mTunerCallback; public: - HalDeathRecipient(wp<V1_1::ITunerCallback> tunerCallback):mTunerCallback(tunerCallback) {} + explicit HalDeathRecipient(wp<V1_1::ITunerCallback> tunerCallback) + : mTunerCallback(tunerCallback) {} virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who); }; diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index 0ff60e44b0ce..024760d46760 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -27,9 +27,11 @@ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> +#include <unordered_map> #include <android/hardware/power/1.0/IPower.h> #include <android/hardware/power/1.1/IPower.h> +#include <android/hardware/power/stats/1.0/IPowerStats.h> #include <android/system/suspend/1.0/ISystemSuspend.h> #include <android/system/suspend/1.0/ISystemSuspendCallback.h> #include <android_runtime/AndroidRuntime.h> @@ -74,6 +76,33 @@ static jmethodID jgetSubsystem = NULL; static jmethodID jputVoter = NULL; static jmethodID jputState = NULL; +std::mutex gPowerHalMutex; +std::unordered_map<uint32_t, std::string> gPowerStatsHalEntityNames = {}; +std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>> + gPowerStatsHalStateNames = {}; +std::vector<uint32_t> gPowerStatsHalPlatformIds = {}; +std::vector<uint32_t> gPowerStatsHalSubsystemIds = {}; +sp<android::hardware::power::stats::V1_0::IPowerStats> gPowerStatsHalV1_0 = nullptr; +std::function<void(JNIEnv*, jobject)> gGetLowPowerStatsImpl = {}; +std::function<jint(JNIEnv*, jobject)> gGetPlatformLowPowerStatsImpl = {}; +std::function<jint(JNIEnv*, jobject)> gGetSubsystemLowPowerStatsImpl = {}; + +// The caller must be holding gPowerHalMutex. +static void deinitPowerStatsLocked() { + gPowerStatsHalV1_0 = nullptr; +} + +struct PowerHalDeathRecipient : virtual public hardware::hidl_death_recipient { + virtual void serviceDied(uint64_t cookie, + const wp<android::hidl::base::V1_0::IBase>& who) override { + // The HAL just died. Reset all handles to HAL services. + std::lock_guard<std::mutex> lock(gPowerHalMutex); + deinitPowerStatsLocked(); + } +}; + +sp<PowerHalDeathRecipient> gDeathRecipient = new PowerHalDeathRecipient(); + class WakeupCallback : public ISystemSuspendCallback { public: Return<void> notifyWakeup(bool success) override { @@ -202,18 +231,291 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) return mergedreasonpos - mergedreason; } -static void getLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject jrpmStats) { - if (jrpmStats == NULL) { - jniThrowException(env, "java/lang/NullPointerException", - "The rpmstats jni input jobject jrpmStats is null."); - return; +// The caller must be holding gPowerHalMutex. +static bool checkResultLocked(const Return<void> &ret, const char* function) { + if (!ret.isOk()) { + ALOGE("%s failed: requested HAL service not available. Description: %s", + function, ret.description().c_str()); + if (ret.isDeadObject()) { + deinitPowerStatsLocked(); + } + return false; } - if (jgetAndUpdatePlatformState == NULL || jgetSubsystem == NULL - || jputVoter == NULL || jputState == NULL) { - ALOGE("A rpmstats jni jmethodID is null."); + return true; +} + +// The caller must be holding gPowerHalMutex. +// gPowerStatsHalV1_0 must not be null +static bool initializePowerStats() { + using android::hardware::power::stats::V1_0::Status; + using android::hardware::power::stats::V1_0::PowerEntityType; + + // Clear out previous content if we are re-initializing + gPowerStatsHalEntityNames.clear(); + gPowerStatsHalStateNames.clear(); + gPowerStatsHalPlatformIds.clear(); + gPowerStatsHalSubsystemIds.clear(); + + Return<void> ret; + ret = gPowerStatsHalV1_0->getPowerEntityInfo([](auto infos, auto status) { + if (status != Status::SUCCESS) { + ALOGE("Error getting power entity info"); + return; + } + + // construct lookup table of powerEntityId to power entity name + // also construct vector of platform and subsystem IDs + for (auto info : infos) { + gPowerStatsHalEntityNames.emplace(info.powerEntityId, info.powerEntityName); + if (info.type == PowerEntityType::POWER_DOMAIN) { + gPowerStatsHalPlatformIds.emplace_back(info.powerEntityId); + } else { + gPowerStatsHalSubsystemIds.emplace_back(info.powerEntityId); + } + } + }); + if (!checkResultLocked(ret, __func__)) { + return false; + } + + ret = gPowerStatsHalV1_0->getPowerEntityStateInfo({}, [](auto stateSpaces, auto status) { + if (status != Status::SUCCESS) { + ALOGE("Error getting state info"); + return; + } + + // construct lookup table of powerEntityId, powerEntityStateId to power entity state name + for (auto stateSpace : stateSpaces) { + std::unordered_map<uint32_t, std::string> stateNames = {}; + for (auto state : stateSpace.states) { + stateNames.emplace(state.powerEntityStateId, + state.powerEntityStateName); + } + gPowerStatsHalStateNames.emplace(stateSpace.powerEntityId, stateNames); + } + }); + if (!checkResultLocked(ret, __func__)) { + return false; + } + + return (!gPowerStatsHalEntityNames.empty()) && (!gPowerStatsHalStateNames.empty()); +} + +// The caller must be holding gPowerHalMutex. +static bool getPowerStatsHalLocked() { + if (gPowerStatsHalV1_0 == nullptr) { + gPowerStatsHalV1_0 = android::hardware::power::stats::V1_0::IPowerStats::getService(); + if (gPowerStatsHalV1_0 == nullptr) { + ALOGE("Unable to get power.stats HAL service."); + return false; + } + + // Link death recipient to power.stats service handle + hardware::Return<bool> linked = gPowerStatsHalV1_0->linkToDeath(gDeathRecipient, 0); + if (!linked.isOk()) { + ALOGE("Transaction error in linking to power.stats HAL death: %s", + linked.description().c_str()); + deinitPowerStatsLocked(); + return false; + } else if (!linked) { + ALOGW("Unable to link to power.stats HAL death notifications"); + // We should still continue even though linking failed + } + return initializePowerStats(); + } + return true; +} + +// The caller must be holding powerHalMutex. +static void getPowerStatsHalLowPowerData(JNIEnv* env, jobject jrpmStats) { + using android::hardware::power::stats::V1_0::Status; + + if (!getPowerStatsHalLocked()) { + ALOGE("failed to get low power stats"); return; } + // Get power entity state residency data + bool success = false; + Return<void> ret = gPowerStatsHalV1_0->getPowerEntityStateResidencyData({}, + [&env, &jrpmStats, &success](auto results, auto status) { + if (status == Status::NOT_SUPPORTED) { + ALOGW("getPowerEntityStateResidencyData is not supported"); + success = false; + return; + } + + for (auto result : results) { + jobject jsubsystem = env->CallObjectMethod(jrpmStats, jgetSubsystem, + env->NewStringUTF(gPowerStatsHalEntityNames.at(result.powerEntityId).c_str())); + if (jsubsystem == NULL) { + ALOGE("The rpmstats jni jobject jsubsystem is null."); + return; + } + for (auto stateResidency : result.stateResidencyData) { + + env->CallVoidMethod(jsubsystem, jputState, + env->NewStringUTF(gPowerStatsHalStateNames.at(result.powerEntityId) + .at(stateResidency.powerEntityStateId).c_str()), + stateResidency.totalTimeInStateMs, + stateResidency.totalStateEntryCount); + } + } + success = true; + }); + checkResultLocked(ret, __func__); + if (!success) { + ALOGE("getPowerEntityStateResidencyData failed"); + } +} + +static jint getPowerStatsHalPlatformData(JNIEnv* env, jobject outBuf) { + using android::hardware::power::stats::V1_0::Status; + using hardware::power::stats::V1_0::PowerEntityStateResidencyResult; + using hardware::power::stats::V1_0::PowerEntityStateResidencyData; + + if (!getPowerStatsHalLocked()) { + ALOGE("failed to get low power stats"); + return -1; + } + + char *output = (char*)env->GetDirectBufferAddress(outBuf); + char *offset = output; + int remaining = (int)env->GetDirectBufferCapacity(outBuf); + int total_added = -1; + + // Get power entity state residency data + Return<void> ret = gPowerStatsHalV1_0->getPowerEntityStateResidencyData( + gPowerStatsHalPlatformIds, + [&offset, &remaining, &total_added](auto results, auto status) { + if (status == Status::NOT_SUPPORTED) { + ALOGW("getPowerEntityStateResidencyData is not supported"); + return; + } + + for (size_t i = 0; i < results.size(); i++) { + const PowerEntityStateResidencyResult& result = results[i]; + + for (size_t j = 0; j < result.stateResidencyData.size(); j++) { + const PowerEntityStateResidencyData& stateResidency = + result.stateResidencyData[j]; + int added = snprintf(offset, remaining, + "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", + j + 1, gPowerStatsHalStateNames.at(result.powerEntityId) + .at(stateResidency.powerEntityStateId).c_str(), + stateResidency.totalTimeInStateMs, + stateResidency.totalStateEntryCount); + if (added < 0) { + break; + } + if (added > remaining) { + added = remaining; + } + offset += added; + remaining -= added; + total_added += added; + } + if (remaining <= 0) { + /* rewrite NULL character*/ + offset--; + total_added--; + ALOGE("power.stats Hal: buffer not enough"); + break; + } + } + }); + if (!checkResultLocked(ret, __func__)) { + return -1; + } + + total_added += 1; + return total_added; +} + +static jint getPowerStatsHalSubsystemData(JNIEnv* env, jobject outBuf) { + using android::hardware::power::stats::V1_0::Status; + using hardware::power::stats::V1_0::PowerEntityStateResidencyResult; + using hardware::power::stats::V1_0::PowerEntityStateResidencyData; + + if (!getPowerStatsHalLocked()) { + ALOGE("failed to get low power stats"); + return -1; + } + + char *output = (char*)env->GetDirectBufferAddress(outBuf); + char *offset = output; + int remaining = (int)env->GetDirectBufferCapacity(outBuf); + int total_added = -1; + + // Get power entity state residency data + Return<void> ret = gPowerStatsHalV1_0->getPowerEntityStateResidencyData( + gPowerStatsHalSubsystemIds, + [&offset, &remaining, &total_added](auto results, auto status) { + if (status == Status::NOT_SUPPORTED) { + ALOGW("getPowerEntityStateResidencyData is not supported"); + return; + } + + int added = snprintf(offset, remaining, "SubsystemPowerState "); + offset += added; + remaining -= added; + total_added += added; + + for (size_t i = 0; i < results.size(); i++) { + const PowerEntityStateResidencyResult& result = results[i]; + added = snprintf(offset, remaining, "subsystem_%zu name=%s ", + i + 1, gPowerStatsHalEntityNames.at(result.powerEntityId).c_str()); + if (added < 0) { + break; + } + + if (added > remaining) { + added = remaining; + } + + offset += added; + remaining -= added; + total_added += added; + + for (size_t j = 0; j < result.stateResidencyData.size(); j++) { + const PowerEntityStateResidencyData& stateResidency = + result.stateResidencyData[j]; + added = snprintf(offset, remaining, + "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " last entry=%" + PRIu64 " ", j + 1, gPowerStatsHalStateNames.at(result.powerEntityId) + .at(stateResidency.powerEntityStateId).c_str(), + stateResidency.totalTimeInStateMs, + stateResidency.totalStateEntryCount, + stateResidency.lastEntryTimestampMs); + if (added < 0) { + break; + } + if (added > remaining) { + added = remaining; + } + offset += added; + remaining -= added; + total_added += added; + } + if (remaining <= 0) { + /* rewrite NULL character*/ + offset--; + total_added--; + ALOGE("power.stats Hal: buffer not enough"); + break; + } + } + }); + if (!checkResultLocked(ret, __func__)) { + return -1; + } + + total_added += 1; + return total_added; +} + +// The caller must be holding powerHalMutex. +static void getPowerHalLowPowerData(JNIEnv* env, jobject jrpmStats) { sp<IPowerV1_0> powerHalV1_0 = getPowerHalV1_0(); if (powerHalV1_0 == nullptr) { ALOGE("Power Hal not loaded"); @@ -286,17 +588,12 @@ static void getLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject jrpmStats processPowerHalReturn(ret, "getSubsystemLowPowerStats"); } -static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) { +static jint getPowerHalPlatformData(JNIEnv* env, jobject outBuf) { char *output = (char*)env->GetDirectBufferAddress(outBuf); char *offset = output; int remaining = (int)env->GetDirectBufferCapacity(outBuf); int total_added = -1; - if (outBuf == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "null argument"); - return -1; - } - { sp<IPowerV1_0> powerHalV1_0 = getPowerHalV1_0(); if (powerHalV1_0 == nullptr) { @@ -365,7 +662,7 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o return total_added; } -static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) { +static jint getPowerHalSubsystemData(JNIEnv* env, jobject outBuf) { char *output = (char*)env->GetDirectBufferAddress(outBuf); char *offset = output; int remaining = (int)env->GetDirectBufferCapacity(outBuf); @@ -374,11 +671,6 @@ static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject // This is a IPower 1.1 API sp<IPowerV1_1> powerHal_1_1 = nullptr; - if (outBuf == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "null argument"); - return -1; - } - { // Trying to get 1.1, this will succeed only for devices supporting 1.1 powerHal_1_1 = getPowerHalV1_1(); @@ -458,6 +750,88 @@ static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject return total_added; } +static void setUpPowerStatsLocked() { + // First see if power.stats HAL is available. Fall back to power HAL if + // power.stats HAL is unavailable. + if (android::hardware::power::stats::V1_0::IPowerStats::getService() != nullptr) { + ALOGI("Using power.stats HAL"); + gGetLowPowerStatsImpl = getPowerStatsHalLowPowerData; + gGetPlatformLowPowerStatsImpl = getPowerStatsHalPlatformData; + gGetSubsystemLowPowerStatsImpl = getPowerStatsHalSubsystemData; + } else if (android::hardware::power::V1_0::IPower::getService() != nullptr) { + ALOGI("Using power HAL"); + gGetLowPowerStatsImpl = getPowerHalLowPowerData; + gGetPlatformLowPowerStatsImpl = getPowerHalPlatformData; + gGetSubsystemLowPowerStatsImpl = getPowerHalSubsystemData; + } +} + +static void getLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject jrpmStats) { + if (jrpmStats == NULL) { + jniThrowException(env, "java/lang/NullPointerException", + "The rpmstats jni input jobject jrpmStats is null."); + return; + } + if (jgetAndUpdatePlatformState == NULL || jgetSubsystem == NULL + || jputVoter == NULL || jputState == NULL) { + ALOGE("A rpmstats jni jmethodID is null."); + return; + } + + std::lock_guard<std::mutex> lock(gPowerHalMutex); + + if (!gGetLowPowerStatsImpl) { + setUpPowerStatsLocked(); + } + + if (gGetLowPowerStatsImpl) { + return gGetLowPowerStatsImpl(env, jrpmStats); + } + + ALOGE("Unable to load Power Hal or power.stats HAL"); + return; +} + +static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) { + if (outBuf == NULL) { + jniThrowException(env, "java/lang/NullPointerException", "null argument"); + return -1; + } + + std::lock_guard<std::mutex> lock(gPowerHalMutex); + + if (!gGetPlatformLowPowerStatsImpl) { + setUpPowerStatsLocked(); + } + + if (gGetPlatformLowPowerStatsImpl) { + return gGetPlatformLowPowerStatsImpl(env, outBuf); + } + + ALOGE("Unable to load Power Hal or power.stats HAL"); + return -1; +} + +static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) { + if (outBuf == NULL) { + jniThrowException(env, "java/lang/NullPointerException", "null argument"); + return -1; + } + + std::lock_guard<std::mutex> lock(gPowerHalMutex); + + if (!gGetSubsystemLowPowerStatsImpl) { + setUpPowerStatsLocked(); + } + + if (gGetSubsystemLowPowerStatsImpl) { + return gGetSubsystemLowPowerStatsImpl(env, outBuf); + } + + ALOGE("Unable to load Power Hal or power.stats HAL"); + return -1; +} + static const JNINativeMethod method_table[] = { { "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup }, { "getLowPowerStats", "(Lcom/android/internal/os/RpmStats;)V", (void*)getLowPowerStats }, diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp index c22109c7816a..b08d13f234ce 100644 --- a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp +++ b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp @@ -89,7 +89,7 @@ public: private: class HdmiCecCallback : public IHdmiCecCallback { public: - HdmiCecCallback(HdmiCecController* controller) : mController(controller) {}; + explicit HdmiCecCallback(HdmiCecController* controller) : mController(controller) {}; Return<void> onCecMessage(const CecMessage& event) override; Return<void> onHotplugEvent(const HotplugEvent& event) override; private: diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 729aed171ab1..6d8fc1c88307 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -104,14 +104,12 @@ using android::String16; using android::hardware::Return; using android::hardware::Void; using android::hardware::hidl_vec; +using android::hardware::hidl_string; using android::hardware::hidl_death_recipient; using android::hardware::gnss::V1_0::GnssConstellationType; using android::hardware::gnss::V1_0::GnssLocation; using android::hardware::gnss::V1_0::GnssLocationFlags; -using android::hardware::gnss::V1_0::IAGnss; -using android::hardware::gnss::V1_0::IAGnssCallback; -using android::hardware::gnss::V1_0::IAGnssCallback; using android::hardware::gnss::V1_0::IAGnssRilCallback; using android::hardware::gnss::V1_0::IGnssBatching; using android::hardware::gnss::V1_0::IGnssBatchingCallback; @@ -145,6 +143,10 @@ using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasur using IGnssMeasurementCallback_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback; using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil; using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil; +using IAGnss_V1_0 = android::hardware::gnss::V1_0::IAGnss; +using IAGnss_V2_0 = android::hardware::gnss::V2_0::IAGnss; +using IAGnssCallback_V1_0 = android::hardware::gnss::V1_0::IAGnssCallback; +using IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback; using IMeasurementCorrections = android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections; @@ -171,7 +173,8 @@ sp<IGnssXtra> gnssXtraIface = nullptr; sp<IAGnssRil_V1_0> agnssRilIface = nullptr; sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr; sp<IGnssGeofencing> gnssGeofencingIface = nullptr; -sp<IAGnss> agnssIface = nullptr; +sp<IAGnss_V1_0> agnssIface = nullptr; +sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr; sp<IGnssBatching> gnssBatchingIface = nullptr; sp<IGnssDebug> gnssDebugIface = nullptr; sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr; @@ -310,6 +313,34 @@ static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa } } +struct ScopedJniString { + ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) { + mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr); + } + + ~ScopedJniString() { + if (mNativeString != nullptr) { + mEnv->ReleaseStringUTFChars(mJavaString, mNativeString); + } + } + + const char* c_str() const { + return mNativeString; + } + + operator hidl_string() const { + return hidl_string(mNativeString); + } + +private: + ScopedJniString(const ScopedJniString&) = delete; + ScopedJniString& operator=(const ScopedJniString&) = delete; + + JNIEnv* mEnv; + jstring mJavaString; + const char* mNativeString; +}; + class ScopedJniThreadAttach { public: ScopedJniThreadAttach() { @@ -1038,21 +1069,21 @@ Return<void> GnssNiCallback::niNotifyCb( } /* - * AGnssCallback implements callback methods required by the IAGnss interface. + * AGnssCallback_V1_0 implements callback methods required by the IAGnssCallback 1.0 interface. */ -struct AGnssCallback : public IAGnssCallback { +struct AGnssCallback_V1_0 : public IAGnssCallback_V1_0 { // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow. Return<void> agnssStatusIpV6Cb( - const IAGnssCallback::AGnssStatusIpV6& agps_status) override; + const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) override; Return<void> agnssStatusIpV4Cb( - const IAGnssCallback::AGnssStatusIpV4& agps_status) override; + const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) override; private: jbyteArray convertToIpV4(uint32_t ip); }; -Return<void> AGnssCallback::agnssStatusIpV6Cb( - const IAGnssCallback::AGnssStatusIpV6& agps_status) { +Return<void> AGnssCallback_V1_0::agnssStatusIpV6Cb( + const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) { JNIEnv* env = getJniEnv(); jbyteArray byteArray = nullptr; @@ -1085,8 +1116,8 @@ Return<void> AGnssCallback::agnssStatusIpV6Cb( return Void(); } -Return<void> AGnssCallback::agnssStatusIpV4Cb( - const IAGnssCallback::AGnssStatusIpV4& agps_status) { +Return<void> AGnssCallback_V1_0::agnssStatusIpV4Cb( + const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) { JNIEnv* env = getJniEnv(); jbyteArray byteArray = nullptr; @@ -1117,7 +1148,7 @@ Return<void> AGnssCallback::agnssStatusIpV4Cb( return Void(); } -jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) { +jbyteArray AGnssCallback_V1_0::convertToIpV4(uint32_t ip) { if (INADDR_NONE == ip) { return nullptr; } @@ -1137,6 +1168,23 @@ jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) { } /* + * AGnssCallback_V2_0 implements callback methods required by the IAGnssCallback 2.0 interface. + */ +struct AGnssCallback_V2_0 : public IAGnssCallback_V2_0 { + // Methods from ::android::hardware::gps::V2_0::IAGnssCallback follow. + Return<void> agnssStatusCb(IAGnssCallback_V2_0::AGnssType type, + IAGnssCallback_V2_0::AGnssStatusValue status) override; +}; + +Return<void> AGnssCallback_V2_0::agnssStatusCb(IAGnssCallback_V2_0::AGnssType type, + IAGnssCallback_V2_0::AGnssStatusValue status) { + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, type, status, nullptr); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +/* * AGnssRilCallback implements the callback methods required by the AGnssRil * interface. */ @@ -1303,11 +1351,20 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass } } - auto gnssAgnss = gnssHal->getExtensionAGnss(); - if (!gnssAgnss.isOk()) { - ALOGD("Unable to get a handle to AGnss"); + if (gnssHal_V2_0 != nullptr) { + auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0(); + if (!agnss_V2_0.isOk()) { + ALOGD("Unable to get a handle to AGnss_V2_0"); + } else { + agnssIface_V2_0 = agnss_V2_0; + } } else { - agnssIface = gnssAgnss; + auto agnss_V1_0 = gnssHal->getExtensionAGnss(); + if (!agnss_V1_0.isOk()) { + ALOGD("Unable to get a handle to AGnss"); + } else { + agnssIface = agnss_V1_0; + } } auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage(); @@ -1453,11 +1510,14 @@ static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject } } - sp<IAGnssCallback> aGnssCbIface = new AGnssCallback(); - if (agnssIface != nullptr) { + if (agnssIface_V2_0 != nullptr) { + sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0(); + agnssIface_V2_0->setCallback(aGnssCbIface); + } else if (agnssIface != nullptr) { + sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0(); agnssIface->setCallback(aGnssCbIface); } else { - ALOGI("Unable to Initialize AGnss interface\n"); + ALOGI("Unable to initialize AGnss interface\n"); } sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback(); @@ -1586,9 +1646,8 @@ static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobje return; } - const char *setid = env->GetStringUTFChars(setid_string, nullptr); - agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, setid); - env->ReleaseStringUTFChars(setid_string, setid); + ScopedJniString jniSetId{env, setid_string}; + agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId); } static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */, @@ -1676,68 +1735,126 @@ static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); } -static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open( - JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) { - if (agnssIface == nullptr) { - ALOGE("no AGPS interface in agps_data_conn_open"); - return; - } - if (apn == nullptr) { - jniThrowException(env, "java/lang/IllegalArgumentException", nullptr); - return; - } +struct AGnssDispatcher { + static void dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn, jint apnIpType); + static void dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env, jlong networkHandle, + jstring apn, jint apnIpType); + + template <class T> + static void dataConnClosed(sp<T> agnssIface); - const char *apnStr = env->GetStringUTFChars(apn, nullptr); + template <class T> + static void dataConnFailed(sp<T> agnssIface); - auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType)); + template <class T, class U> + static void setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname, jint port); + +private: + AGnssDispatcher() = delete; + AGnssDispatcher(const AGnssDispatcher&) = delete; + AGnssDispatcher& operator=(const AGnssDispatcher&) = delete; +}; + +void AGnssDispatcher::dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn, + jint apnIpType) { + ScopedJniString jniApn{env, apn}; + auto result = agnssIface->dataConnOpen(jniApn, + static_cast<IAGnss_V1_0::ApnIpType>(apnIpType)); if (!result.isOk() || !result){ ALOGE("%s: Failed to set APN and its IP type", __func__); } - env->ReleaseStringUTFChars(apn, apnStr); } -static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */, - jobject /* obj */) { - if (agnssIface == nullptr) { - ALOGE("%s: AGPS interface not supported", __func__); - return; +void AGnssDispatcher::dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env, + jlong networkHandle, jstring apn, jint apnIpType) { + ScopedJniString jniApn{env, apn}; + auto result = agnssIface_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn, + static_cast<IAGnss_V2_0::ApnIpType>(apnIpType)); + if (!result.isOk() || !result){ + ALOGE("%s: Failed to set APN and its IP type", __func__); } +} +template<class T> +void AGnssDispatcher::dataConnClosed(sp<T> agnssIface) { auto result = agnssIface->dataConnClosed(); if (!result.isOk() || !result) { ALOGE("%s: Failed to close AGnss data connection", __func__); } } -static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */, +template<class T> +void AGnssDispatcher::dataConnFailed(sp<T> agnssIface) { + auto result = agnssIface->dataConnFailed(); + if (!result.isOk() || !result) { + ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__); + } +} + +template <class T, class U> +void AGnssDispatcher::setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname, + jint port) { + ScopedJniString jniHostName{env, hostname}; + auto result = agnssIface->setServer(static_cast<typename U::AGnssType>(type), + jniHostName, port); + if (!result.isOk() || !result) { + ALOGE("%s: Failed to set AGnss host name and port", __func__); + } +} + +static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open( + JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) { + if (apn == nullptr) { + jniThrowException(env, "java/lang/IllegalArgumentException", nullptr); + return; + } + + if (agnssIface_V2_0 != nullptr) { + AGnssDispatcher::dataConnOpen(agnssIface_V2_0, env, networkHandle, apn, apnIpType); + } else if (agnssIface != nullptr) { + AGnssDispatcher::dataConnOpen(agnssIface, env, apn, apnIpType); + } else { + ALOGE("%s: AGPS interface not supported", __func__); + return; + } +} + +static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */, jobject /* obj */) { - if (agnssIface == nullptr) { + if (agnssIface_V2_0 != nullptr) { + AGnssDispatcher::dataConnClosed(agnssIface_V2_0); + } else if (agnssIface != nullptr) { + AGnssDispatcher::dataConnClosed(agnssIface); + } else { ALOGE("%s: AGPS interface not supported", __func__); return; } +} - auto result = agnssIface->dataConnFailed(); - if (!result.isOk() || !result) { - ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__); +static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */, + jobject /* obj */) { + if (agnssIface_V2_0 != nullptr) { + AGnssDispatcher::dataConnFailed(agnssIface_V2_0); + } else if (agnssIface != nullptr) { + AGnssDispatcher::dataConnFailed(agnssIface); + } else { + ALOGE("%s: AGPS interface not supported", __func__); + return; } } static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */, jint type, jstring hostname, jint port) { - if (agnssIface == nullptr) { - ALOGE("no AGPS interface in set_agps_server"); + if (agnssIface_V2_0 != nullptr) { + AGnssDispatcher::setServer<IAGnss_V2_0, IAGnssCallback_V2_0>(agnssIface_V2_0, env, type, + hostname, port); + } else if (agnssIface != nullptr) { + AGnssDispatcher::setServer<IAGnss_V1_0, IAGnssCallback_V1_0>(agnssIface, env, type, + hostname, port); + } else { + ALOGE("%s: AGPS interface not supported", __func__); return; } - - const char *c_hostname = env->GetStringUTFChars(hostname, nullptr); - auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type), - c_hostname, - port); - if (!result.isOk() || !result) { - ALOGE("%s: Failed to set AGnss host name and port", __func__); - } - - env->ReleaseStringUTFChars(hostname, c_hostname); } static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */, @@ -1832,41 +1949,37 @@ static void android_location_GnssNetworkConnectivityHandler_update_network_state jstring apn, jlong networkHandle, jshort capabilities) { - if (agnssRilIface == nullptr) { - ALOGE("AGnssRilInterface does not exist"); - return; - } - - const char *c_apn = env->GetStringUTFChars(apn, nullptr); - const android::hardware::hidl_string hidl_apn{c_apn}; if (agnssRilIface_V2_0 != nullptr) { + ScopedJniString jniApn{env, apn}; IAGnssRil_V2_0::NetworkAttributes networkAttributes = { .networkHandle = static_cast<uint64_t>(networkHandle), .isConnected = static_cast<bool>(connected), .capabilities = static_cast<uint16_t>(capabilities), - .apn = hidl_apn + .apn = jniApn }; auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes); if (!result.isOk() || !result) { ALOGE("updateNetworkState_2_0 failed"); } - } else { + } else if (agnssRilIface != nullptr) { + ScopedJniString jniApn{env, apn}; + hidl_string hidlApn{jniApn}; auto result = agnssRilIface->updateNetworkState(connected, static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming); if (!result.isOk() || !result) { ALOGE("updateNetworkState failed"); } - if (!hidl_apn.empty()) { - result = agnssRilIface->updateNetworkAvailability(available, hidl_apn); + if (!hidlApn.empty()) { + result = agnssRilIface->updateNetworkAvailability(available, hidlApn); if (!result.isOk() || !result) { ALOGE("updateNetworkAvailability failed"); } } + } else { + ALOGE("AGnssRilInterface does not exist"); } - - env->ReleaseStringUTFChars(apn, c_apn); } static jboolean android_location_GnssGeofenceProvider_is_geofence_supported( @@ -2540,7 +2653,7 @@ static const JNINativeMethod sNetworkConnectivityMethods[] = { "(ZIZZLjava/lang/String;JS)V", reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)}, {"native_agps_data_conn_open", - "(Ljava/lang/String;I)V", + "(JLjava/lang/String;I)V", reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)}, {"native_agps_data_conn_closed", "()V", diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/services/core/jni/com_android_server_security_VerityUtils.cpp index ec94e3c92ed8..3c87e42d926b 100644 --- a/services/core/jni/com_android_server_security_VerityUtils.cpp +++ b/services/core/jni/com_android_server_security_VerityUtils.cpp @@ -20,13 +20,22 @@ #include "jni.h" #include <utils/Log.h> +#include <errno.h> +#include <fcntl.h> #include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <android-base/unique_fd.h> // TODO(112037636): Always include once fsverity.h is upstreamed and backported. #define HAS_FSVERITY 0 #if HAS_FSVERITY #include <linux/fsverity.h> + +const int kSha256Bytes = 32; #endif namespace android { @@ -66,9 +75,26 @@ class JavaByteArrayHolder { jbyte* mElements; }; +int measureFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath) { +#if HAS_FSVERITY + auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_digest) + kSha256Bytes); + fsverity_digest* data = reinterpret_cast<fsverity_digest*>(raii->getRaw()); + data->digest_size = kSha256Bytes; // the only input/output parameter + + const char* path = env->GetStringUTFChars(filePath, nullptr); + ::android::base::unique_fd rfd(open(path, O_RDONLY)); + if (ioctl(rfd.get(), FS_IOC_MEASURE_VERITY, data) < 0) { + return errno; + } + return 0; +#else + LOG_ALWAYS_FATAL("fs-verity is used while not enabled"); + return -1; +#endif // HAS_FSVERITY +} + jbyteArray constructFsveritySignedData(JNIEnv* env, jobject /* clazz */, jbyteArray digest) { #if HAS_FSVERITY - const int kSha256Bytes = 32; auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_digest_disk) + kSha256Bytes); fsverity_digest_disk* data = reinterpret_cast<fsverity_digest_disk*>(raii->getRaw()); @@ -146,6 +172,7 @@ jbyteArray constructFsverityFooter(JNIEnv* env, jobject /* clazz */, } const JNINativeMethod sMethods[] = { + { "measureFsverityNative", "(Ljava/lang/String;)I", (void *)measureFsverity }, { "constructFsveritySignedDataNative", "([B)[B", (void *)constructFsveritySignedData }, { "constructFsverityDescriptorNative", "(J)[B", (void *)constructFsverityDescriptor }, { "constructFsverityExtensionNative", "(SI)[B", (void *)constructFsverityExtension }, diff --git a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp index c8f842dde7ae..e51963340ae1 100644 --- a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp +++ b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp @@ -74,7 +74,7 @@ public: } } - operator bool() { + explicit operator bool() { return mLocked; } diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index 6c2a894a3a6a..098b2ef6439d 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -292,7 +292,7 @@ private: class TvInputCallback : public ITvInputCallback { public: - TvInputCallback(JTvInputHal* hal); + explicit TvInputCallback(JTvInputHal* hal); Return<void> notify(const TvInputEvent& event) override; private: JTvInputHal* mHal; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 409e7f4d6bdb..781e1c4a41d9 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -9293,19 +9293,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { InputMethodManager inputMethodManager = mContext.getSystemService(InputMethodManager.class); List<InputMethodInfo> imes = inputMethodManager.getInputMethodList(); - long id = mInjector.binderClearCallingIdentity(); - try { - if (imes != null) { - for (InputMethodInfo ime : imes) { - ServiceInfo serviceInfo = ime.getServiceInfo(); - ApplicationInfo applicationInfo = serviceInfo.applicationInfo; - if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - result.add(serviceInfo.packageName); - } + if (imes != null) { + for (InputMethodInfo ime : imes) { + ServiceInfo serviceInfo = ime.getServiceInfo(); + ApplicationInfo applicationInfo = serviceInfo.applicationInfo; + if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + result.add(serviceInfo.packageName); } } - } finally { - mInjector.binderRestoreCallingIdentity(id); } } return result; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 046c9912dee3..855fb508ec64 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -63,6 +63,7 @@ import android.util.EventLog; import android.util.Slog; import android.util.TimingsTraceLog; import android.view.WindowManager; +import android.view.inputmethod.InputMethodSystemProperty; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; @@ -122,6 +123,7 @@ import com.android.server.power.ShutdownThread; import com.android.server.power.ThermalManagerService; import com.android.server.restrictions.RestrictionsManagerService; import com.android.server.role.RoleManagerService; +import com.android.server.rollback.RollbackManagerService; import com.android.server.security.KeyAttestationApplicationIdProviderService; import com.android.server.security.KeyChainSystemService; import com.android.server.signedconfig.SignedConfigService; @@ -778,6 +780,11 @@ public final class SystemServer { traceBeginAndSlog("StartLooperStatsService"); mSystemServiceManager.startService(LooperStatsService.Lifecycle.class); traceEnd(); + + // Manages apk rollbacks. + traceBeginAndSlog("StartRollbackManagerService"); + mSystemServiceManager.startService(RollbackManagerService.Lifecycle.class); + traceEnd(); } /** @@ -1019,7 +1026,7 @@ public final class SystemServer { // Bring up services needed for UI. if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) { traceBeginAndSlog("StartInputMethodManagerLifecycle"); - if (MultiClientInputMethodManagerService.isConfiguredToUse()) { + if (InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) { mSystemServiceManager.startService( MultiClientInputMethodManagerService.Lifecycle.class); } else { @@ -1263,6 +1270,16 @@ public final class SystemServer { } traceEnd(); + traceBeginAndSlog("StartNetworkStack"); + try { + final android.net.NetworkStack networkStack = + context.getSystemService(android.net.NetworkStack.class); + networkStack.start(context); + } catch (Throwable e) { + reportWtf("starting Network Stack", e); + } + traceEnd(); + traceBeginAndSlog("StartNsdService"); try { serviceDiscovery = NsdService.create(context); diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java index 1e468d44b8c7..bb60c27a2543 100644 --- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java +++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java @@ -71,7 +71,6 @@ import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowContextWrapper; import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowPackageManager; -import org.robolectric.shadows.ShadowSettings; import java.io.File; import java.util.List; @@ -433,7 +432,7 @@ public class UserBackupManagerServiceTest { } private String getSettingsTransport() { - return ShadowSettings.ShadowSecure.getString( + return Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.BACKUP_TRANSPORT); } diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java index cf51e19edb00..5e84ab0d66f7 100644 --- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java +++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java @@ -134,7 +134,6 @@ import org.mockito.stubbing.Answer; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowApplication; import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.shadows.ShadowQueuedWork; @@ -188,7 +187,6 @@ public class KeyValueBackupTaskTest { private File mBaseStateDir; private File mDataDir; private Application mApplication; - private ShadowApplication mShadowApplication; private Looper mMainLooper; private FrameworkShadowLooper mShadowMainLooper; private Context mContext; @@ -200,7 +198,6 @@ public class KeyValueBackupTaskTest { mTransport = backupTransport(); mApplication = RuntimeEnvironment.application; - mShadowApplication = shadowOf(mApplication); mContext = mApplication; mMainLooper = Looper.getMainLooper(); @@ -2439,7 +2436,7 @@ public class KeyValueBackupTaskTest { packageData.packageName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); PackageInfo packageInfo = getPackageInfo(packageData); mShadowPackageManager.addPackage(packageInfo); - mShadowApplication.sendBroadcast(getPackageAddedIntent(packageData)); + mContext.sendBroadcast(getPackageAddedIntent(packageData)); // Run the backup looper because on the receiver we post MSG_SCHEDULE_BACKUP_PACKAGE mShadowBackupLooper.runToEndOfTasks(); BackupAgent backupAgent = spy(BackupAgent.class); diff --git a/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java b/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java index 859392d80d36..4009876314e8 100644 --- a/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java +++ b/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java @@ -479,8 +479,11 @@ public class ActiveRestoreSessionTest { @Test public void testRestorePackage_whenCallerIsNotPackageAndPermissionGranted() throws Exception { - mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP); - ShadowBinder.setCallingUid(1); + final int pid = 1211; + final int uid = 1; + mShadowApplication.grantPermissions(pid, uid, android.Manifest.permission.BACKUP); + ShadowBinder.setCallingPid(pid); + ShadowBinder.setCallingUid(uid); setUpPackage(PACKAGE_1, /* uid */ 2); when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1); setUpTransport(mTransport); @@ -494,8 +497,11 @@ public class ActiveRestoreSessionTest { @Test public void testRestorePackage_whenCallerIsNotPackageAndPermissionDenied() throws Exception { - mShadowApplication.denyPermissions(android.Manifest.permission.BACKUP); - ShadowBinder.setCallingUid(1); + final int pid = 1211; + final int uid = 1; + mShadowApplication.denyPermissions(pid, uid, android.Manifest.permission.BACKUP); + ShadowBinder.setCallingPid(pid); + ShadowBinder.setCallingUid(uid); setUpPackage(PACKAGE_1, /* uid */ 2); when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1); setUpTransport(mTransport); @@ -508,7 +514,11 @@ public class ActiveRestoreSessionTest { @Test public void testRestorePackage_whenPackageNotFound() throws Exception { - mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP); + final int pid = 1211; + final int uid = 1; + mShadowApplication.grantPermissions(pid, uid, android.Manifest.permission.BACKUP); + ShadowBinder.setCallingPid(pid); + ShadowBinder.setCallingUid(uid); setUpPackage(PACKAGE_1, /* uid */ 1); setUpTransport(mTransport); IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport); diff --git a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java index b9785707fe96..47abcc5a2dd1 100644 --- a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java +++ b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java @@ -136,11 +136,13 @@ public class BackupManagerServiceTestUtils { } public static void setUpBinderCallerAndApplicationAsSystem(Application application) { - ShadowBinder.setCallingUid(Process.SYSTEM_UID); - ShadowBinder.setCallingPid(1211); + final int uid = Process.SYSTEM_UID; + final int pid = 1211; + ShadowBinder.setCallingUid(uid); + ShadowBinder.setCallingPid(pid); ShadowApplication shadowApplication = shadowOf(application); - shadowApplication.grantPermissions("android.permission.BACKUP"); - shadowApplication.grantPermissions("android.permission.CONFIRM_FULL_BACKUP"); + shadowApplication.grantPermissions(pid, uid, "android.permission.BACKUP"); + shadowApplication.grantPermissions(pid, uid, "android.permission.CONFIRM_FULL_BACKUP"); } /** diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java index cff0521bba50..1a16e568ca53 100644 --- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java @@ -46,9 +46,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import android.app.ActivityManagerInternal; import android.app.AlarmManager; @@ -56,6 +58,7 @@ import android.app.IActivityManager; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.hardware.Sensor; import android.hardware.SensorManager; import android.location.LocationManager; import android.location.LocationProvider; @@ -70,6 +73,7 @@ import android.os.SystemClock; import androidx.test.runner.AndroidJUnit4; +import com.android.server.deviceidle.ConstraintController; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; @@ -77,6 +81,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; @@ -89,6 +94,7 @@ public class DeviceIdleControllerTest { private DeviceIdleController mDeviceIdleController; private AnyMotionDetectorForTest mAnyMotionDetector; private AppStateTrackerForTest mAppStateTracker; + private DeviceIdleController.Constants mConstants; private InjectorForTest mInjector; private MockitoSession mMockingSession; @@ -97,7 +103,7 @@ public class DeviceIdleControllerTest { @Mock private ConnectivityService mConnectivityService; @Mock - private DeviceIdleController.Constants mConstants; + private ContentResolver mContentResolver; @Mock private IActivityManager mIActivityManager; @Mock @@ -108,10 +114,13 @@ public class DeviceIdleControllerTest { private PowerManager.WakeLock mWakeLock; @Mock private PowerManagerInternal mPowerManagerInternal; + @Mock + private SensorManager mSensorManager; class InjectorForTest extends DeviceIdleController.Injector { ConnectivityService connectivityService; LocationManager locationManager; + ConstraintController constraintController; InjectorForTest(Context ctx) { super(ctx); @@ -139,37 +148,51 @@ public class DeviceIdleControllerTest { } @Override - DeviceIdleController.Constants getConstants(DeviceIdleController controller, - Handler handler, - ContentResolver resolver) { - return mConstants; - } - - @Override LocationManager getLocationManager() { return locationManager; } @Override DeviceIdleController.MyHandler getHandler(DeviceIdleController controller) { - return mock(DeviceIdleController.MyHandler.class); + return mock(DeviceIdleController.MyHandler.class, Answers.RETURNS_DEEP_STUBS); } @Override PowerManager getPowerManager() { return mPowerManager; } + + @Override + SensorManager getSensorManager() { + return mSensorManager; + } + + @Override + ConstraintController getConstraintController( + Handler handler, DeviceIdleController.LocalService localService) { + return constraintController; + } + + @Override + boolean useMotionSensor() { + return true; + } } private class AnyMotionDetectorForTest extends AnyMotionDetector { boolean isMonitoring = false; AnyMotionDetectorForTest() { - super(mPowerManager, mock(Handler.class), mock(SensorManager.class), + super(mPowerManager, mock(Handler.class), mSensorManager, mock(DeviceIdleCallback.class), 0.5f); } @Override + public boolean hasSensor() { + return true; + } + + @Override public void checkForAnyMotion() { isMonitoring = true; } @@ -201,7 +224,7 @@ public class DeviceIdleControllerTest { mMockingSession = mockitoSession() .initMocks(this) .strictness(Strictness.LENIENT) - .mockStatic(LocalServices.class) + .spyStatic(LocalServices.class) .startMocking(); spyOn(getContext()); doReturn(null).when(getContext()).registerReceiver(any(), any()); @@ -218,9 +241,13 @@ public class DeviceIdleControllerTest { when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock); doNothing().when(mWakeLock).acquire(); doNothing().when(mAlarmManager).set(anyInt(), anyLong(), anyString(), any(), any()); + doReturn(mock(Sensor.class)).when(mSensorManager) + .getDefaultSensor(eq(Sensor.TYPE_SIGNIFICANT_MOTION), eq(true)); + doReturn(true).when(mSensorManager).registerListener(any(), any(), anyInt()); mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper()); mAnyMotionDetector = new AnyMotionDetectorForTest(); mInjector = new InjectorForTest(getContext()); + doNothing().when(mContentResolver).registerContentObserver(any(), anyBoolean(), any()); mDeviceIdleController = new DeviceIdleController(getContext(), mInjector); spyOn(mDeviceIdleController); doNothing().when(mDeviceIdleController).publishBinderService(any(), any()); @@ -228,6 +255,10 @@ public class DeviceIdleControllerTest { mDeviceIdleController.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); mDeviceIdleController.setDeepEnabledForTest(true); mDeviceIdleController.setLightEnabledForTest(true); + + // Get the same Constants object that mDeviceIdleController got. + mConstants = mInjector.getConstants(mDeviceIdleController, + mInjector.getHandler(mDeviceIdleController), mContentResolver); } @After @@ -235,9 +266,10 @@ public class DeviceIdleControllerTest { if (mMockingSession != null) { mMockingSession.finishMocking(); } - // DeviceIdleController adds this to LocalServices in the constructor, so we have to remove - // it after each test, otherwise, subsequent tests will fail. + // DeviceIdleController adds these to LocalServices in the constructor, so we have to remove + // them after each test, otherwise, subsequent tests will fail. LocalServices.removeServiceForTest(AppStateTracker.class); + LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class); } @Test @@ -1456,8 +1488,8 @@ public class DeviceIdleControllerTest { private void setAlarmSoon(boolean isSoon) { if (isSoon) { - doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when( - mAlarmManager).getNextWakeFromIdleTime(); + doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2) + .when(mAlarmManager).getNextWakeFromIdleTime(); } else { doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime(); } @@ -1481,27 +1513,36 @@ public class DeviceIdleControllerTest { assertFalse(mDeviceIdleController.isScreenOn()); break; case STATE_IDLE_PENDING: - assertTrue(mDeviceIdleController.mMotionListener.isActive()); + assertEquals( + mDeviceIdleController.hasMotionSensor(), + mDeviceIdleController.mMotionListener.isActive()); assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); break; case STATE_SENSING: - assertTrue(mDeviceIdleController.mMotionListener.isActive()); - assertTrue(mAnyMotionDetector.isMonitoring); + assertEquals( + mDeviceIdleController.hasMotionSensor(), + mDeviceIdleController.mMotionListener.isActive()); + assertEquals( + mDeviceIdleController.hasMotionSensor(), + mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); break; case STATE_LOCATING: - assertTrue(mDeviceIdleController.mMotionListener.isActive()); - assertTrue(mAnyMotionDetector.isMonitoring); + assertEquals( + mDeviceIdleController.hasMotionSensor(), + mDeviceIdleController.mMotionListener.isActive()); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); break; case STATE_IDLE: - assertTrue(mDeviceIdleController.mMotionListener.isActive() + if (mDeviceIdleController.hasMotionSensor()) { + assertTrue(mDeviceIdleController.mMotionListener.isActive() // If quick doze is enabled, the motion listener should NOT be active. || mDeviceIdleController.isQuickDozeEnabled()); + } assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); @@ -1509,9 +1550,11 @@ public class DeviceIdleControllerTest { verifyLightStateConditions(LIGHT_STATE_OVERRIDE); break; case STATE_IDLE_MAINTENANCE: - assertTrue(mDeviceIdleController.mMotionListener.isActive() + if (mDeviceIdleController.hasMotionSensor()) { + assertTrue(mDeviceIdleController.mMotionListener.isActive() // If quick doze is enabled, the motion listener should NOT be active. || mDeviceIdleController.isQuickDozeEnabled()); + } assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); diff --git a/services/tests/mockingservicestests/src/com/android/server/deviceidle/BluetoothConstraintTest.java b/services/tests/mockingservicestests/src/com/android/server/deviceidle/BluetoothConstraintTest.java new file mode 100644 index 000000000000..f74ac1f5317f --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/deviceidle/BluetoothConstraintTest.java @@ -0,0 +1,147 @@ +/* + * 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.server.deviceidle; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; + +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.eq; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.DeviceIdleController; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; + +import java.util.Arrays; + +/** + * Tests for {@link com.android.server.deviceidle.BluetoothConstraint}. + */ +@RunWith(AndroidJUnit4.class) +public class BluetoothConstraintTest { + + private MockitoSession mMockingSession; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Handler mHandler; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private BluetoothManager mBluetoothManager; + + @Mock + private DeviceIdleController.LocalService mDeviceIdleService; + + private BluetoothConstraint mConstraint; + + @Before + public void setUp() { + mMockingSession = mockitoSession() + .initMocks(this) + .strictness(Strictness.LENIENT) + .startMocking(); + doReturn(mBluetoothManager) + .when(mContext).getSystemService(BluetoothManager.class); + mConstraint = new BluetoothConstraint(mContext, mHandler, mDeviceIdleService); + } + + @After + public void tearDown() { + if (mMockingSession != null) { + mMockingSession.finishMocking(); + } + } + + @Test + public void testIsConnected_noBluetoothAdapter() { + doReturn(null).when(mBluetoothManager).getAdapter(); + assertFalse(BluetoothConstraint.isBluetoothConnected(mBluetoothManager)); + } + + @Test + public void testIsConnected_noConnectedDevice() { + enableBluetooth(true); + assertFalse(BluetoothConstraint.isBluetoothConnected(mBluetoothManager)); + } + + @Test + public void testIsConnected_twoConnectedDevices() { + enableBluetooth(true, mock(BluetoothDevice.class), mock(BluetoothDevice.class)); + assertTrue(BluetoothConstraint.isBluetoothConnected(mBluetoothManager)); + } + + @Test + public void testStartMonitoring_updatesActiveAtCorrectTimes() { + // First setup -> no callbacks should fire. + BluetoothConstraint constraint = mConstraint; + verify(mDeviceIdleService, never()).onConstraintStateChanged(any(), anyBoolean()); + verify(mContext, never()).registerReceiver(eq(constraint.mReceiver), any()); + + InOrder order = inOrder(mDeviceIdleService); + + // No devices -> active=false should be triggered. + enableBluetooth(true); + constraint.startMonitoring(); + order.verify(mDeviceIdleService, times(1)).onConstraintStateChanged(any(), eq(false)); + + // One device -> active=true should be triggered. + enableBluetooth(true, mock(BluetoothDevice.class)); + constraint.mReceiver.onReceive( + mContext, new Intent(BluetoothDevice.ACTION_ACL_CONNECTED)); + constraint.startMonitoring(); + order.verify(mDeviceIdleService, times(1)).exitIdle(eq("bluetooth")); + + // Stop monitoring -> broadcast receiver should be unregistered. + constraint.stopMonitoring(); + verify(mContext, times(1)).unregisterReceiver(eq(constraint.mReceiver)); + order.verifyNoMoreInteractions(); + + } + + private void enableBluetooth(boolean enabled, BluetoothDevice... devices) { + when(mBluetoothManager.getAdapter().isEnabled()).thenReturn(enabled); + when(mBluetoothManager.getConnectedDevices(eq(BluetoothProfile.GATT))) + .thenReturn(Arrays.asList(devices)); + } +} diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java index e02a30def3dc..db83505900c5 100644 --- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java @@ -510,19 +510,6 @@ public class TrampolineTest { } @Test - public void setBackupProvisioned_calledBeforeInitialize_ignored() throws RemoteException { - mTrampoline.setBackupProvisioned(true); - verifyNoMoreInteractions(mBackupManagerServiceMock); - } - - @Test - public void setBackupProvisioned_forwarded() throws RemoteException { - mTrampoline.initializeService(); - mTrampoline.setBackupProvisioned(true); - verifyNoMoreInteractions(mBackupManagerServiceMock); - } - - @Test public void isBackupEnabled_calledBeforeInitialize_ignored() throws RemoteException { assertFalse(mTrampoline.isBackupEnabled()); verifyNoMoreInteractions(mBackupManagerServiceMock); diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp index 7a5eaa852c34..f4443fe81a00 100644 --- a/services/tests/uiservicestests/Android.bp +++ b/services/tests/uiservicestests/Android.bp @@ -20,6 +20,7 @@ android_test { "android-support-test", "mockito-target-inline-minus-junit4", "platform-test-annotations", + "hamcrest-library", "testables", ], diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java new file mode 100644 index 000000000000..fa90b291eeee --- /dev/null +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java @@ -0,0 +1,270 @@ +/* + * 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.server.notification; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertSame; + +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +// this is a lazy way to do in/out/err but we're not particularly interested in the output +import static java.io.FileDescriptor.err; +import static java.io.FileDescriptor.in; +import static java.io.FileDescriptor.out; + +import android.app.INotificationManager; +import android.app.Notification; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.Icon; +import android.os.Binder; +import android.os.Handler; +import android.os.ResultReceiver; +import android.os.ShellCallback; +import android.os.UserHandle; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableContext; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; + +import com.android.server.UiServiceTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.List; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class NotificationShellCmdTest extends UiServiceTestCase { + private final Binder mBinder = new Binder(); + private final ShellCallback mCallback = new ShellCallback(); + private final TestableContext mTestableContext = spy(getContext()); + @Mock + NotificationManagerService mMockService; + @Mock + INotificationManager mMockBinderService; + private TestableLooper mTestableLooper; + private ResultReceiver mResultReceiver; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mTestableLooper = TestableLooper.get(this); + mResultReceiver = new ResultReceiver(new Handler(mTestableLooper.getLooper())); + + when(mMockService.getContext()).thenReturn(mTestableContext); + when(mMockService.getBinderService()).thenReturn(mMockBinderService); + } + + private Bitmap createTestBitmap() { + final Bitmap bits = Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(bits); + final GradientDrawable grad = new GradientDrawable(GradientDrawable.Orientation.TL_BR, + new int[]{Color.RED, Color.YELLOW, Color.GREEN, + Color.CYAN, Color.BLUE, Color.MAGENTA}); + grad.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + grad.draw(canvas); + return bits; + } + + private void doCmd(String... args) { + new NotificationShellCmd(mMockService) + .exec(mBinder, in, out, err, args, mCallback, mResultReceiver); + } + + @Test + public void testNoArgs() throws Exception { + doCmd(); + } + + @Test + public void testHelp() throws Exception { + doCmd("--help"); + } + + Notification captureNotification(String aTag) throws Exception { + ArgumentCaptor<Notification> notificationCaptor = + ArgumentCaptor.forClass(Notification.class); + verify(mMockBinderService).enqueueNotificationWithTag( + eq(NotificationShellCmd.NOTIFICATION_PACKAGE), + eq("android"), + eq(aTag), + eq(NotificationShellCmd.NOTIFICATION_ID), + notificationCaptor.capture(), + eq(UserHandle.getCallingUserId())); + return notificationCaptor.getValue(); + } + + @Test + public void testBasic() throws Exception { + final String aTag = "aTag"; + final String aText = "someText"; + final String aTitle = "theTitle"; + doCmd("notify", + "--title", aTitle, + aTag, aText); + final Notification captured = captureNotification(aTag); + assertEquals(aText, captured.extras.getString(Notification.EXTRA_TEXT)); + assertEquals(aTitle, captured.extras.getString(Notification.EXTRA_TITLE)); + } + + @Test + public void testIcon() throws Exception { + final String aTag = "aTag"; + final String aText = "someText"; + doCmd("notify", "--icon", "@android:drawable/stat_sys_adb", aTag, aText); + final Notification captured = captureNotification(aTag); + final Icon icon = captured.getSmallIcon(); + assertEquals("android", icon.getResPackage()); + assertEquals(com.android.internal.R.drawable.stat_sys_adb, icon.getResId()); + } + + @Test + public void testBigText() throws Exception { + final String aTag = "aTag"; + final String aText = "someText"; + final String bigText = "someBigText"; + doCmd("notify", + "--style", "bigtext", + "--big-text", bigText, + aTag, aText); + final Notification captured = captureNotification(aTag); + assertSame(captured.getNotificationStyle(), Notification.BigTextStyle.class); + assertEquals(aText, captured.extras.getString(Notification.EXTRA_TEXT)); + assertEquals(bigText, captured.extras.getString(Notification.EXTRA_BIG_TEXT)); + } + + @Test + public void testBigPicture() throws Exception { + final String aTag = "aTag"; + final String aText = "someText"; + final String bigPicture = "@android:drawable/default_wallpaper"; + doCmd("notify", + "--style", "bigpicture", + "--picture", bigPicture, + aTag, aText); + final Notification captured = captureNotification(aTag); + assertSame(captured.getNotificationStyle(), Notification.BigPictureStyle.class); + final Object pic = captured.extras.get(Notification.EXTRA_PICTURE); + assertThat(pic, instanceOf(Bitmap.class)); + } + + @Test + public void testInbox() throws Exception { + final int n = 25; + final String aTag = "inboxTag"; + final String aText = "inboxText"; + ArrayList<String> args = new ArrayList<>(); + args.add("notify"); + args.add("--style"); + args.add("inbox"); + final int startOfLineArgs = args.size(); + for (int i = 0; i < n; i++) { + args.add("--line"); + args.add(String.format("Line %02d", i)); + } + args.add(aTag); + args.add(aText); + + doCmd(args.toArray(new String[0])); + final Notification captured = captureNotification(aTag); + assertSame(captured.getNotificationStyle(), Notification.InboxStyle.class); + final Notification.Builder builder = + Notification.Builder.recoverBuilder(mContext, captured); + final ArrayList<CharSequence> lines = + ((Notification.InboxStyle) (builder.getStyle())).getLines(); + for (int i = 0; i < n; i++) { + assertEquals(lines.get(i), args.get(1 + 2 * i + startOfLineArgs)); + } + } + + static final String[] PEOPLE = { + "Alice", + "Bob", + "Charlotte" + }; + static final String[] MESSAGES = { + "Shall I compare thee to a summer's day?", + "Thou art more lovely and more temperate:", + "Rough winds do shake the darling buds of May,", + "And summer's lease hath all too short a date;", + "Sometime too hot the eye of heaven shines,", + "And often is his gold complexion dimm'd;", + "And every fair from fair sometime declines,", + "By chance or nature's changing course untrimm'd;", + "But thy eternal summer shall not fade,", + "Nor lose possession of that fair thou ow'st;", + "Nor shall death brag thou wander'st in his shade,", + "When in eternal lines to time thou grow'st:", + " So long as men can breathe or eyes can see,", + " So long lives this, and this gives life to thee.", + }; + + @Test + public void testMessaging() throws Exception { + final String aTag = "messagingTag"; + final String aText = "messagingText"; + ArrayList<String> args = new ArrayList<>(); + args.add("notify"); + args.add("--style"); + args.add("messaging"); + args.add("--conversation"); + args.add("Sonnet 18"); + final int startOfLineArgs = args.size(); + for (int i = 0; i < MESSAGES.length; i++) { + args.add("--message"); + args.add(String.format("%s:%s", + PEOPLE[i % PEOPLE.length], + MESSAGES[i % MESSAGES.length])); + } + args.add(aTag); + args.add(aText); + + doCmd(args.toArray(new String[0])); + final Notification captured = captureNotification(aTag); + assertSame(Notification.MessagingStyle.class, captured.getNotificationStyle()); + final Notification.Builder builder = + Notification.Builder.recoverBuilder(mContext, captured); + final Notification.MessagingStyle messagingStyle = + (Notification.MessagingStyle) (builder.getStyle()); + + assertEquals("Sonnet 18", messagingStyle.getConversationTitle()); + final List<Notification.MessagingStyle.Message> messages = messagingStyle.getMessages(); + for (int i = 0; i < messages.size(); i++) { + final Notification.MessagingStyle.Message m = messages.get(i); + assertEquals(MESSAGES[i], m.getText()); + assertEquals(PEOPLE[i % PEOPLE.length], m.getSenderPerson().getName()); + } + + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index dc3287e690a8..a459b0a26932 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -61,6 +61,7 @@ import android.provider.Settings.Global; import android.service.notification.Condition; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ScheduleInfo; +import android.service.notification.ZenPolicy; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -683,6 +684,92 @@ public class ZenModeHelperTest extends UiServiceTestCase { } @Test + public void testWriteXmlWithZenPolicy() throws Exception { + final String ruleId = "customRule"; + setupZenConfig(); + + // one enabled automatic rule with zen policy + ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>(); + ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule(); + final ScheduleInfo customRuleInfo = new ScheduleInfo(); + customRule.enabled = true; + customRule.creationTime = 0; + customRule.id = "customRule"; + customRule.name = "Custom Rule"; + customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); + customRule.configurationActivity = + new ComponentName("android", "ScheduleConditionProvider"); + customRule.pkg = customRule.configurationActivity.getPackageName(); + customRule.zenPolicy = new ZenPolicy.Builder() + .allowAlarms(false) + .allowMedia(false) + .allowRepeatCallers(false) + .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE) + .allowMessages(ZenPolicy.PEOPLE_TYPE_CONTACTS) + .allowEvents(true) + .allowReminders(false) + .build(); + automaticRules.put("customRule", customRule); + mZenModeHelperSpy.mConfig.automaticRules = automaticRules; + + ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy(); + + ByteArrayOutputStream baos = writeXmlAndPurge(false, null); + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream( + new ByteArrayInputStream(baos.toByteArray())), null); + parser.nextTag(); + mZenModeHelperSpy.readXml(parser, false); + + ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId); + ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId); + + assertEquals("Automatic rules mismatch", original, current); + } + + @Test + public void testReadXmlRestoreWithZenPolicy() throws Exception { + final String ruleId = "customRule"; + setupZenConfig(); + + // one enabled automatic rule with zen policy + ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>(); + ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule(); + final ScheduleInfo customRuleInfo = new ScheduleInfo(); + customRule.enabled = true; + customRule.creationTime = 0; + customRule.id = ruleId; + customRule.name = "Custom Rule"; + customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; + customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); + customRule.configurationActivity = + new ComponentName("android", "ScheduleConditionProvider"); + customRule.pkg = customRule.configurationActivity.getPackageName(); + customRule.zenPolicy = new ZenPolicy.Builder() + .allowSystem(true) + .allowCalls(ZenPolicy.PEOPLE_TYPE_ANYONE) + .allowReminders(true) + .build(); + automaticRules.put(ruleId, customRule); + mZenModeHelperSpy.mConfig.automaticRules = automaticRules; + + ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy(); + + ByteArrayOutputStream baos = writeXmlAndPurge(false, null); + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream( + new ByteArrayInputStream(baos.toByteArray())), null); + parser.nextTag(); + mZenModeHelperSpy.readXml(parser, true); + + ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId); + ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId); + + assertEquals("Automatic rules mismatch", original, current); + } + + @Test public void testReadXmlRulesNotOverriden() throws Exception { setupZenConfig(); @@ -896,6 +983,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); customRule.component = new ComponentName("android", "ScheduleConditionProvider"); + customRule.zenPolicy = new ZenPolicy.Builder() + .allowReminders(true) + .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE) + .build(); automaticRules.put("customRule", customRule); ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule(); @@ -943,6 +1034,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); customRule.component = new ComponentName("android", "ScheduleConditionProvider"); + customRule.zenPolicy = new ZenPolicy.Builder() + .allowReminders(true) + .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE) + .build(); automaticRules.put("customRule", customRule); ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule(); @@ -953,6 +1048,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId( defaultScheduleRuleInfo); defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID; + defaultScheduleRule.zenPolicy = new ZenPolicy.Builder() + .allowEvents(true) + .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE) + .build(); automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule); ZenModeConfig.ZenRule defaultEventRule = new ZenModeConfig.ZenRule(); @@ -963,6 +1062,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { defaultEventRule.conditionId = ZenModeConfig.toScheduleConditionId( defaultEventRuleInfo); defaultEventRule.id = ZenModeConfig.EVENTS_DEFAULT_RULE_ID; + defaultScheduleRule.zenPolicy = new ZenPolicy.Builder() + .allowAlarms(false) + .allowMedia(false) + .allowRepeatCallers(false) + .build(); automaticRules.put(ZenModeConfig.EVENTS_DEFAULT_RULE_ID, defaultEventRule); mZenModeHelperSpy.mConfig.automaticRules = automaticRules; diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java index dc057d564a84..b315e514d6a6 100644 --- a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java +++ b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java @@ -101,4 +101,34 @@ public class SlicePermissionManagerTest extends UiServiceTestCase { assertTrue(FileUtils.deleteContentsAndDir(sliceDir)); } -}
\ No newline at end of file + @Test + public void testInvalid() throws Exception { + File sliceDir = new File(mContext.getCacheDir(), "slices-test"); + if (!sliceDir.exists()) { + sliceDir.mkdir(); + } + SlicePermissionManager permissions = new SlicePermissionManager(mContext, + TestableLooper.get(this).getLooper(), sliceDir); + + DirtyTracker.Persistable junk = new DirtyTracker.Persistable() { + @Override + public String getFileName() { + return "invalidData"; + } + + @Override + public void writeTo(XmlSerializer out) throws IOException { + throw new RuntimeException("this doesn't work"); + } + }; + + // let's put something bad in here + permissions.addDirtyImmediate(junk); + // force a persist. if this throws, it would take down system_server + permissions.handlePersist(); + + // Cleanup. + assertTrue(FileUtils.deleteContentsAndDir(sliceDir)); + } + +} 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 92b4dbb5076b..bc62de12373d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -155,15 +155,17 @@ public class AppWindowTokenTests extends WindowTestsBase { // Set initial orientation and update. mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); - mWm.updateOrientationFromAppTokens(mDisplayContent.getRequestedOverrideConfiguration(), - null, mDisplayContent.getDisplayId()); + mDisplayContent.updateOrientationFromAppTokens( + mDisplayContent.getRequestedOverrideConfiguration(), + null /* freezeThisOneIfNeeded */, false /* forceUpdate */); assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation()); appWindow.mResizeReported = false; // Update the orientation to perform 180 degree rotation and check that resize was reported. mToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE); - mWm.updateOrientationFromAppTokens(mDisplayContent.getRequestedOverrideConfiguration(), - null, mDisplayContent.getDisplayId()); + mDisplayContent.updateOrientationFromAppTokens( + mDisplayContent.getRequestedOverrideConfiguration(), + null /* freezeThisOneIfNeeded */, false /* forceUpdate */); mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */); assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation()); assertTrue(appWindow.mResizeReported); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 8430616731d2..3826fac22b05 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -31,7 +31,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.same; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; @@ -60,9 +66,11 @@ import android.view.Surface; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; +import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Test; +import org.mockito.ArgumentCaptor; import java.util.ArrayList; import java.util.Arrays; @@ -475,6 +483,13 @@ public class DisplayContentTests extends WindowTestsBase { @SuppressLint("InlinedApi") public void testOrientationDefinedByKeyguard() { final DisplayContent dc = createNewDisplay(); + + // When display content is created its configuration is not yet initialized, which could + // cause unnecessary configuration propagation, so initialize it here. + final Configuration config = new Configuration(); + dc.computeScreenConfiguration(config); + dc.onRequestedOverrideConfigurationChanged(config); + // Create a window that requests landscape orientation. It will define device orientation // by default. final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); @@ -567,6 +582,52 @@ public class DisplayContentTests extends WindowTestsBase { assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget); } + @Test + public void testOnDescendantOrientationRequestChanged() { + final DisplayContent dc = createNewDisplay(); + mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class); + final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE + ? SCREEN_ORIENTATION_PORTRAIT + : SCREEN_ORIENTATION_LANDSCAPE; + + final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); + window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS); + window.mAppToken.setOrientation(newOrientation); + + ActivityRecord activityRecord = mock(ActivityRecord.class); + + assertTrue("Display should rotate to handle orientation request by default.", + dc.onDescendantOrientationChanged(window.mToken.token, activityRecord)); + + final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class); + verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(), + same(activityRecord), anyBoolean(), eq(dc.getDisplayId())); + final Configuration newDisplayConfig = captor.getValue(); + assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation); + } + + @Test + public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() { + final DisplayContent dc = createNewDisplay(); + dc.getDisplayRotation().setFixedToUserRotation(true); + mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class); + final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE + ? SCREEN_ORIENTATION_PORTRAIT + : SCREEN_ORIENTATION_LANDSCAPE; + + final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w"); + window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS); + window.mAppToken.setOrientation(newOrientation); + + ActivityRecord activityRecord = mock(ActivityRecord.class); + + assertFalse("Display shouldn't rotate to handle orientation request if fixed to" + + " user rotation.", + dc.onDescendantOrientationChanged(window.mToken.token, activityRecord)); + verify(mWm.mAtmService, never()).updateDisplayOverrideConfigurationLocked(any(), + eq(activityRecord), anyBoolean(), eq(dc.getDisplayId())); + } + private boolean isOptionsPanelAtRight(int displayId) { return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index bf4b52eb72aa..6b31e6fdbd28 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -33,6 +33,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.content.ContentResolver; @@ -234,7 +235,7 @@ public class DisplayRotationTests { } @Test - public void testReturnsSidesays_UserRotationLocked_IncompatibleAppRequest() + public void testReturnsSideways_UserRotationLocked_IncompatibleAppRequest() throws Exception { mBuilder.build(); configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false); @@ -604,6 +605,26 @@ public class DisplayRotationTests { SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0)); } + // ======================== + // Non-rotation API Tests + // ======================== + @Test + public void testRespectsAppRequestedOrientationByDefault() throws Exception { + mBuilder.build(); + + assertTrue("Display rotation should respect app requested orientation by" + + " default.", mTarget.respectAppRequestedOrientation()); + } + + @Test + public void testNotRespectAppRequestedOrientation_FixedToUserRotation() throws Exception { + mBuilder.build(); + mTarget.setFixedToUserRotation(true); + + assertFalse("Display rotation shouldn't respect app requested orientation if" + + " fixed to user rotation.", mTarget.respectAppRequestedOrientation()); + } + /** * Call {@link DisplayRotation#configure(int, int, int, int)} to configure {@link #mTarget} * according to given parameters. diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java index 8e881b54c422..992d01766344 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java @@ -22,10 +22,10 @@ import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -43,11 +43,13 @@ import android.view.Surface; import androidx.test.filters.SmallTest; +import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.server.policy.WindowManagerPolicy; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.MockitoSession; import java.io.File; @@ -94,6 +96,12 @@ public class DisplayWindowSettingsTests extends WindowTestsBase { @After public void tearDown() { deleteRecursively(TEST_FOLDER); + + // TODO(b/121296525): We may want to restore other display settings (not only overscans in + // testPersistOverscan*test) on mPrimaryDisplay and mSecondaryDisplay back to default + // values after each test finishes, since we are going to reuse a singleton + // WindowManagerService instance among all tests that extend {@link WindowTestsBase} class + // (b/113239988). } @Test @@ -245,21 +253,35 @@ public class DisplayWindowSettingsTests extends WindowTestsBase { @Test public void testPersistOverscanInSameInstance() { final DisplayInfo info = mPrimaryDisplay.getDisplayInfo(); - mTarget.setOverscanLocked(info, 1 /* left */, 2 /* top */, 3 /* right */, 4 /* bottom */); + try { + mTarget.setOverscanLocked(info, 1 /* left */, 2 /* top */, 3 /* right */, + 4 /* bottom */); - mTarget.applySettingsToDisplayLocked(mPrimaryDisplay); + mTarget.applySettingsToDisplayLocked(mPrimaryDisplay); - assertOverscan(mPrimaryDisplay, 1 /* left */, 2 /* top */, 3 /* right */, 4 /* bottom */); + assertOverscan(mPrimaryDisplay, 1 /* left */, 2 /* top */, 3 /* right */, + 4 /* bottom */); + } finally { + mTarget.setOverscanLocked(info, 0, 0, 0, 0); + mTarget.applySettingsToDisplayLocked(mPrimaryDisplay); + } } @Test public void testPersistOverscanAcrossInstances() { final DisplayInfo info = mPrimaryDisplay.getDisplayInfo(); - mTarget.setOverscanLocked(info, 1 /* left */, 2 /* top */, 3 /* right */, 4 /* bottom */); + try { + mTarget.setOverscanLocked(info, 10 /* left */, 20 /* top */, 30 /* right */, + 40 /* bottom */); - applySettingsToDisplayByNewInstance(mPrimaryDisplay); + applySettingsToDisplayByNewInstance(mPrimaryDisplay); - assertOverscan(mPrimaryDisplay, 1 /* left */, 2 /* top */, 3 /* right */, 4 /* bottom */); + assertOverscan(mPrimaryDisplay, 10 /* left */, 20 /* top */, 30 /* right */, + 40 /* bottom */); + } finally { + mTarget.setOverscanLocked(info, 0, 0, 0, 0); + mTarget.applySettingsToDisplayLocked(mPrimaryDisplay); + } } @Test @@ -389,26 +411,32 @@ public class DisplayWindowSettingsTests extends WindowTestsBase { mTarget.setUserRotation(mPrimaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED, Surface.ROTATION_0); + final MockitoSession mockitoSession = ExtendedMockito.mockitoSession() + .startMocking(); final DisplayRotation displayRotation = mock(DisplayRotation.class); - mPrimaryDisplay = spy(mPrimaryDisplay); - when(mPrimaryDisplay.getDisplayRotation()).thenReturn(displayRotation); + spyOn(mPrimaryDisplay); + doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation(); mTarget.applySettingsToDisplayLocked(mPrimaryDisplay); verify(displayRotation).restoreSettings(anyInt(), anyInt(), eq(false)); + mockitoSession.finishMocking(); } @Test public void testSetFixedToUserRotation() { mTarget.setFixedToUserRotation(mPrimaryDisplay, true); + final MockitoSession mockitoSession = ExtendedMockito.mockitoSession() + .startMocking(); final DisplayRotation displayRotation = mock(DisplayRotation.class); - mPrimaryDisplay = spy(mPrimaryDisplay); - when(mPrimaryDisplay.getDisplayRotation()).thenReturn(displayRotation); + spyOn(mPrimaryDisplay); + doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation(); applySettingsToDisplayByNewInstance(mPrimaryDisplay); verify(displayRotation).restoreSettings(anyInt(), anyInt(), eq(true)); + mockitoSession.finishMocking(); } private static void assertOverscan(DisplayContent display, int left, int top, int right, diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java index 8821544903c1..374078625f4a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java @@ -19,13 +19,19 @@ package com.android.server.wm; import static android.view.InsetsState.TYPE_TOP_BAR; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.InsetsSource; +import android.view.InsetsState; +import org.junit.Before; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; @@ -81,4 +87,41 @@ public class InsetsSourceProviderTest extends WindowTestsBase { mProvider.onPostLayout(); assertEquals(new Rect(10, 10, 20, 20), mProvider.getSource().getFrame()); } + + @Test + public void testUpdateControlForTarget() { + final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow"); + final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); + topBar.getFrameLw().set(0, 0, 500, 100); + mProvider.setWindow(topBar, null); + mProvider.updateControlForTarget(target); + assertNotNull(mProvider.getControl()); + mProvider.updateControlForTarget(null); + assertNull(mProvider.getControl()); + } + + @Test + public void testInsetsModified() { + final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow"); + final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); + topBar.getFrameLw().set(0, 0, 500, 100); + mProvider.setWindow(topBar, null); + mProvider.updateControlForTarget(target); + InsetsState state = new InsetsState(); + state.getSource(TYPE_TOP_BAR).setVisible(false); + mProvider.onInsetsModified(target, state.getSource(TYPE_TOP_BAR)); + assertFalse(mSource.isVisible()); + } + + @Test + public void testInsetsModified_noControl() { + final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow"); + final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); + topBar.getFrameLw().set(0, 0, 500, 100); + mProvider.setWindow(topBar, null); + InsetsState state = new InsetsState(); + state.getSource(TYPE_TOP_BAR).setVisible(false); + mProvider.onInsetsModified(target, state.getSource(TYPE_TOP_BAR)); + assertTrue(mSource.isVisible()); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 60f957f8f569..e1561436c022 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -27,6 +27,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyFloat; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; @@ -38,8 +39,10 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; +import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.view.SurfaceControl; import android.view.SurfaceSession; @@ -559,8 +562,7 @@ public class WindowContainerTests extends WindowTestsBase { builder.setLayer(2).setIsVisible(true); final TestWindowContainer visibleUnspecifiedRootChildChildFillsParent = visibleUnspecifiedRootChild.addChildWindow(builder); - visibleUnspecifiedRootChildChildFillsParent.setOrientation( - SCREEN_ORIENTATION_PORTRAIT); + visibleUnspecifiedRootChildChildFillsParent.setOrientation(SCREEN_ORIENTATION_PORTRAIT); assertEquals(SCREEN_ORIENTATION_PORTRAIT, visibleUnspecifiedRootChildChildFillsParent.getOrientation()); assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnspecifiedRootChild.getOrientation()); @@ -724,6 +726,19 @@ public class WindowContainerTests extends WindowTestsBase { verify(grandChild, times(1)).onParentResize(); } + @Test + public void testOnDescendantOrientationRequestChangedPropagation() { + final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm); + final TestWindowContainer root = spy(builder.build()); + + final IBinder binder = mock(IBinder.class); + final ActivityRecord activityRecord = mock(ActivityRecord.class); + final TestWindowContainer child = root.addChildWindow(); + + child.setOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED, binder, activityRecord); + verify(root).onDescendantOrientationChanged(binder, activityRecord); + } + /* Used so we can gain access to some protected members of the {@link WindowContainer} class */ private static class TestWindowContainer extends WindowContainer<TestWindowContainer> { private final int mLayer; diff --git a/startop/view_compiler/TEST_MAPPING b/startop/view_compiler/TEST_MAPPING index 5d675b76b395..700607536890 100644 --- a/startop/view_compiler/TEST_MAPPING +++ b/startop/view_compiler/TEST_MAPPING @@ -2,6 +2,10 @@ "presubmit": [ { "name": "dex-builder-test" + }, + { + "name": "view-compiler-tests", + "host": true } ] } diff --git a/startop/view_compiler/main.cc b/startop/view_compiler/main.cc index 55bfdc78ec1b..609bcf377b46 100644 --- a/startop/view_compiler/main.cc +++ b/startop/view_compiler/main.cc @@ -32,6 +32,7 @@ namespace { using namespace tinyxml2; +using namespace startop::util; using std::string; constexpr char kStdoutFilename[]{"stdout"}; diff --git a/startop/view_compiler/util.cc b/startop/view_compiler/util.cc index 69df41dff3d7..a0637e6da32f 100644 --- a/startop/view_compiler/util.cc +++ b/startop/view_compiler/util.cc @@ -18,6 +18,9 @@ using std::string; +namespace startop { +namespace util { + // TODO: see if we can borrow this from somewhere else, like aapt2. string FindLayoutNameFromFilename(const string& filename) { size_t start = filename.rfind("/"); @@ -30,3 +33,6 @@ string FindLayoutNameFromFilename(const string& filename) { return filename.substr(start, end - start); } + +} // namespace util +} // namespace startop diff --git a/startop/view_compiler/util.h b/startop/view_compiler/util.h index 03e093920bfa..0176175920c1 100644 --- a/startop/view_compiler/util.h +++ b/startop/view_compiler/util.h @@ -13,11 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef UTIL_H_ -#define UTIL_H_ +#ifndef VIEW_COMPILER_UTIL_H_ +#define VIEW_COMPILER_UTIL_H_ #include <string> +namespace startop { +namespace util { + std::string FindLayoutNameFromFilename(const std::string& filename); -#endif // UTIL_H_ +} // namespace util +} // namespace startop + +#endif // VIEW_COMPILER_UTIL_H_ diff --git a/startop/view_compiler/util_test.cc b/startop/view_compiler/util_test.cc index d1540d3a6e43..50682a04e3b1 100644 --- a/startop/view_compiler/util_test.cc +++ b/startop/view_compiler/util_test.cc @@ -20,9 +20,15 @@ using std::string; +namespace startop { +namespace util { + TEST(UtilTest, FindLayoutNameFromFilename) { - EXPECT_EQ("bar", ::FindLayoutNameFromFilename("foo/bar.xml")); - EXPECT_EQ("bar", ::FindLayoutNameFromFilename("bar.xml")); - EXPECT_EQ("bar", ::FindLayoutNameFromFilename("./foo/bar.xml")); - EXPECT_EQ("bar", ::FindLayoutNameFromFilename("/foo/bar.xml")); + EXPECT_EQ("bar", startop::util::FindLayoutNameFromFilename("foo/bar.xml")); + EXPECT_EQ("bar", startop::util::FindLayoutNameFromFilename("bar.xml")); + EXPECT_EQ("bar", startop::util::FindLayoutNameFromFilename("./foo/bar.xml")); + EXPECT_EQ("bar", startop::util::FindLayoutNameFromFilename("/foo/bar.xml")); } + +} // namespace util +} // namespace startop diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 0589cd4a538e..84256037b379 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -614,6 +614,11 @@ public abstract class Connection extends Conferenceable { public static final String EVENT_HANDOVER_FAILED = "android.telecom.event.HANDOVER_FAILED"; + /** + * Connection extra key used to store SIP invite fields for an incoming call for IMS calls + */ + public static final String EXTRA_SIP_INVITE = "android.telecom.extra.SIP_INVITE"; + // Flag controlling whether PII is emitted into the logs private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG); diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java index 097e3529dead..5dedb045566c 100644 --- a/telecomm/java/android/telecom/PhoneAccountHandle.java +++ b/telecomm/java/android/telecom/PhoneAccountHandle.java @@ -168,7 +168,7 @@ public final class PhoneAccountHandle implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private PhoneAccountHandle(Parcel in) { this(ComponentName.CREATOR.createFromParcel(in), in.readString(), diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index f87472d9ec38..a9a128bf6681 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1793,17 +1793,6 @@ public class CarrierConfigManager { "editable_wfc_roaming_mode_bool"; /** - * Determine whether current lpp_mode used for E-911 needs to be kept persistently. - * {@code false} - not keeping the lpp_mode means using default configuration of gps.conf - * when sim is not presented. - * {@code true} - current lpp_profile of carrier will be kepted persistently - * even after sim is removed. - * - * @hide - */ - public static final String KEY_PERSIST_LPP_MODE_BOOL = "persist_lpp_mode_bool"; - - /** * Carrier specified WiFi networks. * @hide */ @@ -2000,6 +1989,8 @@ public class CarrierConfigManager { * Determine whether to use only RSRP for the number of LTE signal bars. * @hide */ + // FIXME: this key and related keys must not be exposed without a consistent philosophy for + // all RATs. public static final String KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL = "use_only_rsrp_for_lte_signal_bar_bool"; @@ -2243,6 +2234,8 @@ public class CarrierConfigManager { * Currently this only supports the value "rscp" * @hide */ + // FIXME: this key and related keys must not be exposed without a consistent philosophy for + // all RATs. public static final String KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING = "wcdma_default_signal_strength_measurement_string"; @@ -2428,6 +2421,114 @@ public class CarrierConfigManager { public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT = "opportunistic_network_exit_threshold_rssnr_int"; + /** + * GPS configs. See android.hardware.gnss@1.0 IGnssConfiguration. + * @hide + */ + public static final class Gps { + /** Prefix of all Gps.KEY_* constants. */ + public static final String KEY_PREFIX = "gps."; + + /** + * Determine whether current lpp_mode used for E-911 needs to be kept persistently. + * {@code false} - not keeping the lpp_mode means using default configuration of gps.conf + * when sim is not presented. + * {@code true} - current lpp_profile of carrier will be kepted persistently + * even after sim is removed. This is default. + */ + public static final String KEY_PERSIST_LPP_MODE_BOOL = KEY_PREFIX + "persist_lpp_mode_bool"; + + /** + * SUPL server host for SET Initiated & non-ES Network-Initiated SUPL requests. + * Default to supl.google.com + */ + public static final String KEY_SUPL_HOST_STRING = KEY_PREFIX + "supl_host"; + + /** SUPL server port. Default to 7275. */ + public static final String KEY_SUPL_PORT_STRING = KEY_PREFIX + "supl_port"; + + /** + * The SUPL version requested by Carrier. This is a bit mask + * with bits 0:7 representing a service indicator field, bits 8:15 + * representing the minor version and bits 16:23 representing the + * major version. Default to 0x20000. + */ + public static final String KEY_SUPL_VER_STRING = KEY_PREFIX + "supl_ver"; + + /** + * SUPL_MODE configuration bit mask + * 1 - Mobile Station Based. This is default. + * 2 - Mobile Station Assisted. + */ + public static final String KEY_SUPL_MODE_STRING = KEY_PREFIX + "supl_mode"; + + /** + * Whether to limit responses to SUPL ES mode requests only during user emergency sessions + * (e.g. E911), and SUPL non-ES requests to only outside of non user emergency sessions. + * 0 - no. + * 1 - yes. This is default. + */ + // TODO(b/119567985): name this key properly + public static final String KEY_SUPL_ES_STRING = KEY_PREFIX + "supl_es"; + + /** + * LTE Positioning Profile settings bit mask. + * 0 - Radio Resource Location Protocol in user plane and control plane. This is default. + * 1 - Enable LTE Positioning Protocol in user plane. + * 2 - Enable LTE Positioning Protocol in control plane. + */ + public static final String KEY_LPP_PROFILE_STRING = KEY_PREFIX + "lpp_profile"; + + /** + * Determine whether to use emergency PDN for emergency SUPL. + * 0 - no. + * 1 - yes. This is default. + */ + public static final String KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING = + KEY_PREFIX + "use_emergency_pdn_for_emergency_supl"; + + /** + * A_GLONASS_POS_PROTOCOL_SELECT bit mask. + * 0 - Don't use A-GLONASS. This is default. + * 1 - Use A-GLONASS in Radio Resource Control(RRC) control-plane. + * 2 - Use A-GLONASS in Radio Resource Location user-plane. + * 4 - Use A-GLONASS in LTE Positioning Protocol User plane. + */ + public static final String KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING = + KEY_PREFIX + "a_glonass_pos_protocol_select"; + + /** + * GPS_LOCK configuration bit mask to specify GPS device behavior toward other services, + * when Location Settings are off. + * "0" - No lock. + * "1" - Lock Mobile Originated GPS functionalities. + * "2" - Lock Network initiated GPS functionalities. + * "3" - Lock both. This is default. + */ + public static final String KEY_GPS_LOCK_STRING = KEY_PREFIX + "gps_lock"; + + /** + * SUPL NI emergency extension time in seconds. Default to "0". + */ + public static final String KEY_ES_EXTENSION_SEC = KEY_PREFIX + "es_extension_sec"; + + private static PersistableBundle getDefaults() { + PersistableBundle defaults = new PersistableBundle(); + defaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, true); + defaults.putString(KEY_SUPL_HOST_STRING, "supl.google.com"); + defaults.putString(KEY_SUPL_PORT_STRING, "7275"); + defaults.putString(KEY_SUPL_VER_STRING, "0x20000"); + defaults.putString(KEY_SUPL_MODE_STRING, "1"); + defaults.putString(KEY_SUPL_ES_STRING, "1"); + defaults.putString(KEY_LPP_PROFILE_STRING, "0"); + defaults.putString(KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING, "1"); + defaults.putString(KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, "0"); + defaults.putString(KEY_GPS_LOCK_STRING, "3"); + defaults.putString(KEY_ES_EXTENSION_SEC, "0"); + return defaults; + } + } + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -2720,7 +2821,6 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null); sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false); sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false); - sDefaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, true); sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null); sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1); sDefaults.putInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1); @@ -2797,6 +2897,7 @@ public class CarrierConfigManager { sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 45); /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_MODERATE */ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, 10); + sDefaults.putAll(Gps.getDefaults()); } /** diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java index 598f56769ca3..fa198674c58a 100644 --- a/telephony/java/android/telephony/CellIdentityCdma.java +++ b/telephony/java/android/telephony/CellIdentityCdma.java @@ -16,7 +16,6 @@ package android.telephony; -import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.telephony.cdma.CdmaCellLocation; @@ -71,30 +70,13 @@ public final class CellIdentityCdma extends CellIdentity { * to 2592000 * @param lat Latitude is a decimal number ranges from -1296000 * to 1296000 - * - * @hide - */ - @UnsupportedAppUsage - public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat) { - this(nid, sid, bid, lon, lat, null, null); - } - - /** - * public constructor - * @param nid Network Id 0..65535 - * @param sid CDMA System Id 0..32767 - * @param bid Base Station Id 0..65535 - * @param lon Longitude is a decimal number ranges from -2592000 - * to 2592000 - * @param lat Latitude is a decimal number ranges from -1296000 - * to 1296000 * @param alphal long alpha Operator Name String or Enhanced Operator Name String * @param alphas short alpha Operator Name String or Enhanced Operator Name String * * @hide */ - public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat, String alphal, - String alphas) { + public CellIdentityCdma( + int nid, int sid, int bid, int lon, int lat, String alphal, String alphas) { super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas); mNetworkId = nid; mSystemId = sid; @@ -107,6 +89,17 @@ public final class CellIdentityCdma extends CellIdentity { } } + /** @hide */ + public CellIdentityCdma(android.hardware.radio.V1_0.CellIdentityCdma cid) { + this(cid.networkId, cid.systemId, cid.baseStationId, cid.longitude, cid.latitude, "", ""); + } + + /** @hide */ + public CellIdentityCdma(android.hardware.radio.V1_2.CellIdentityCdma cid) { + this(cid.base.networkId, cid.base.systemId, cid.base.baseStationId, cid.base.longitude, + cid.base.latitude, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort); + } + private CellIdentityCdma(CellIdentityCdma cid) { this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude, cid.mAlphaLong, cid.mAlphaShort); diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index c8a899b339c6..9a24e47288c3 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -36,10 +36,8 @@ public final class CellIdentityGsm extends CellIdentity { // 16-bit GSM Cell Identity described in TS 27.007, 0..65535 private final int mCid; // 16-bit GSM Absolute RF Channel Number - @UnsupportedAppUsage private final int mArfcn; // 6-bit Base Station Identity Code - @UnsupportedAppUsage private final int mBsic; /** @@ -53,34 +51,6 @@ public final class CellIdentityGsm extends CellIdentity { mArfcn = CellInfo.UNAVAILABLE; mBsic = CellInfo.UNAVAILABLE; } - /** - * public constructor - * @param mcc 3-digit Mobile Country Code, 0..999 - * @param mnc 2 or 3-digit Mobile Network Code, 0..999 - * @param lac 16-bit Location Area Code, 0..65535 - * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity - * - * @hide - */ - public CellIdentityGsm(int mcc, int mnc, int lac, int cid) { - this(lac, cid, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, - String.valueOf(mcc), String.valueOf(mnc), null, null); - } - - /** - * public constructor - * @param mcc 3-digit Mobile Country Code, 0..999 - * @param mnc 2 or 3-digit Mobile Network Code, 0..999 - * @param lac 16-bit Location Area Code, 0..65535 - * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity - * @param arfcn 16-bit GSM Absolute RF Channel Number - * @param bsic 6-bit Base Station Identity Code - * - * @hide - */ - public CellIdentityGsm(int mcc, int mnc, int lac, int cid, int arfcn, int bsic) { - this(lac, cid, arfcn, bsic, String.valueOf(mcc), String.valueOf(mnc), null, null); - } /** * public constructor @@ -101,9 +71,21 @@ public final class CellIdentityGsm extends CellIdentity { mLac = lac; mCid = cid; mArfcn = arfcn; - // In RIL BSIC is a UINT8, so 0xFF is the 'INVALID' designator - // for inbound parcels - mBsic = (bsic == 0xFF) ? CellInfo.UNAVAILABLE : bsic; + mBsic = bsic; + } + + /** @hide */ + public CellIdentityGsm(android.hardware.radio.V1_0.CellIdentityGsm cid) { + this(cid.lac, cid.cid, cid.arfcn, + cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic, + cid.mcc, cid.mnc, "", ""); + } + + /** @hide */ + public CellIdentityGsm(android.hardware.radio.V1_2.CellIdentityGsm cid) { + this(cid.base.lac, cid.base.cid, cid.base.arfcn, + cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc, + cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort); } private CellIdentityGsm(CellIdentityGsm cid) { diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index 8e1877d8e35f..51393b90e61e 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; @@ -38,7 +39,6 @@ public final class CellIdentityLte extends CellIdentity { // 16-bit tracking area code private final int mTac; // 18-bit Absolute RF Channel Number - @UnsupportedAppUsage private final int mEarfcn; // cell bandwidth, in kHz private final int mBandwidth; @@ -66,7 +66,7 @@ public final class CellIdentityLte extends CellIdentity { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public CellIdentityLte(int mcc, int mnc, int ci, int pci, int tac) { this(ci, pci, tac, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, String.valueOf(mcc), String.valueOf(mnc), null, null); @@ -74,22 +74,6 @@ public final class CellIdentityLte extends CellIdentity { /** * - * @param mcc 3-digit Mobile Country Code, 0..999 - * @param mnc 2 or 3-digit Mobile Network Code, 0..999 - * @param ci 28-bit Cell Identity - * @param pci Physical Cell Id 0..503 - * @param tac 16-bit Tracking Area Code - * @param earfcn 18-bit LTE Absolute RF Channel Number - * - * @hide - */ - public CellIdentityLte(int mcc, int mnc, int ci, int pci, int tac, int earfcn) { - this(ci, pci, tac, earfcn, CellInfo.UNAVAILABLE, String.valueOf(mcc), String.valueOf(mnc), - null, null); - } - - /** - * * @param ci 28-bit Cell Identity * @param pci Physical Cell Id 0..503 * @param tac 16-bit Tracking Area Code @@ -112,6 +96,18 @@ public final class CellIdentityLte extends CellIdentity { mBandwidth = bandwidth; } + /** @hide */ + public CellIdentityLte(android.hardware.radio.V1_0.CellIdentityLte cid) { + this(cid.ci, cid.pci, cid.tac, cid.earfcn, CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", ""); + } + + /** @hide */ + public CellIdentityLte(android.hardware.radio.V1_2.CellIdentityLte cid) { + this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth, + cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, + cid.operatorNames.alphaShort); + } + private CellIdentityLte(CellIdentityLte cid) { this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr, cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort); diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index f77c468d2f5e..38143335dbf1 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -51,22 +51,6 @@ public final class CellIdentityTdscdma extends CellIdentity { } /** - * @param mcc 3-digit Mobile Country Code, 0..999 - * @param mnc 2 or 3-digit Mobile Network Code, 0..999 - * @param lac 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown - * @param cid 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, CellInfo. - * UNAVAILABLE if unknown - * @param cpid 8-bit Cell Parameters ID described in TS 25.331, 0..127, CellInfo.UNAVAILABLE - * if unknown - * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3 - * - * @hide - */ - public CellIdentityTdscdma(int mcc, int mnc, int lac, int cid, int cpid, int uarfcn) { - this(String.valueOf(mcc), String.valueOf(mnc), lac, cid, cpid, uarfcn, null, null); - } - - /** * @param mcc 3-digit Mobile Country Code in string format * @param mnc 2 or 3-digit Mobile Network Code in string format * @param lac 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown @@ -94,6 +78,17 @@ public final class CellIdentityTdscdma extends CellIdentity { cid.mCpid, cid.mUarfcn, cid.mAlphaLong, cid.mAlphaShort); } + /** @hide */ + public CellIdentityTdscdma(android.hardware.radio.V1_0.CellIdentityTdscdma cid) { + this(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, CellInfo.UNAVAILABLE, "", ""); + } + + /** @hide */ + public CellIdentityTdscdma(android.hardware.radio.V1_2.CellIdentityTdscdma cid) { + this(cid.base.mcc, cid.base.mnc, cid.base.lac, cid.base.cid, cid.base.cpid, + cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort); + } + CellIdentityTdscdma copy() { return new CellIdentityTdscdma(this); } diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index 31f9e6d5bb90..6e0978434a57 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -51,35 +51,6 @@ public final class CellIdentityWcdma extends CellIdentity { mPsc = CellInfo.UNAVAILABLE; mUarfcn = CellInfo.UNAVAILABLE; } - /** - * public constructor - * @param mcc 3-digit Mobile Country Code, 0..999 - * @param mnc 2 or 3-digit Mobile Network Code, 0..999 - * @param lac 16-bit Location Area Code, 0..65535 - * @param cid 28-bit UMTS Cell Identity - * @param psc 9-bit UMTS Primary Scrambling Code - * - * @hide - */ - public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc) { - this(lac, cid, psc, CellInfo.UNAVAILABLE, String.valueOf(mcc), String.valueOf(mnc), - null, null); - } - - /** - * public constructor - * @param mcc 3-digit Mobile Country Code, 0..999 - * @param mnc 2 or 3-digit Mobile Network Code, 0..999 - * @param lac 16-bit Location Area Code, 0..65535 - * @param cid 28-bit UMTS Cell Identity - * @param psc 9-bit UMTS Primary Scrambling Code - * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3 - * - * @hide - */ - public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc, int uarfcn) { - this(lac, cid, psc, uarfcn, String.valueOf(mcc), String.valueOf(mnc), null, null); - } /** * public constructor @@ -103,6 +74,18 @@ public final class CellIdentityWcdma extends CellIdentity { mUarfcn = uarfcn; } + /** @hide */ + public CellIdentityWcdma(android.hardware.radio.V1_0.CellIdentityWcdma cid) { + this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", ""); + } + + /** @hide */ + public CellIdentityWcdma(android.hardware.radio.V1_2.CellIdentityWcdma cid) { + this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn, + cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, + cid.operatorNames.alphaShort); + } + private CellIdentityWcdma(CellIdentityWcdma cid) { this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr, cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort); diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index d0b268766314..b761bd7bf70c 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -132,7 +132,8 @@ public abstract class CellInfo implements Parcelable { /** Connection status is unknown. */ public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE; - private int mCellConnectionStatus = CONNECTION_NONE; + /** A cell connection status */ + private int mCellConnectionStatus; // True if device is mRegistered to the mobile network private boolean mRegistered; @@ -144,6 +145,7 @@ public abstract class CellInfo implements Parcelable { protected CellInfo() { this.mRegistered = false; this.mTimeStamp = Long.MAX_VALUE; + mCellConnectionStatus = CONNECTION_NONE; } /** @hide */ @@ -300,4 +302,44 @@ public abstract class CellInfo implements Parcelable { return new CellInfo[size]; } }; + + /** @hide */ + protected CellInfo(android.hardware.radio.V1_0.CellInfo ci) { + this.mRegistered = ci.registered; + this.mTimeStamp = ci.timeStamp; + this.mCellConnectionStatus = CONNECTION_UNKNOWN; + } + + /** @hide */ + protected CellInfo(android.hardware.radio.V1_2.CellInfo ci) { + this.mRegistered = ci.registered; + this.mTimeStamp = ci.timeStamp; + this.mCellConnectionStatus = ci.connectionStatus; + } + + /** @hide */ + public static CellInfo create(android.hardware.radio.V1_0.CellInfo ci) { + if (ci == null) return null; + switch(ci.cellInfoType) { + case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci); + case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci); + case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci); + case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci); + case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci); + default: return null; + } + } + + /** @hide */ + public static CellInfo create(android.hardware.radio.V1_2.CellInfo ci) { + if (ci == null) return null; + switch(ci.cellInfoType) { + case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci); + case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci); + case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci); + case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci); + case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci); + default: return null; + } + } } diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java index f67733d63ef2..c9f07dab6bbd 100644 --- a/telephony/java/android/telephony/CellInfoCdma.java +++ b/telephony/java/android/telephony/CellInfoCdma.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Rlog; @@ -41,13 +42,31 @@ public final class CellInfoCdma extends CellInfo implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public CellInfoCdma(CellInfoCdma ci) { super(ci); this.mCellIdentityCdma = ci.mCellIdentityCdma.copy(); this.mCellSignalStrengthCdma = ci.mCellSignalStrengthCdma.copy(); } + /** @hide */ + public CellInfoCdma(android.hardware.radio.V1_0.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_0.CellInfoCdma cic = ci.cdma.get(0); + mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma); + mCellSignalStrengthCdma = + new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo); + } + + /** @hide */ + public CellInfoCdma(android.hardware.radio.V1_2.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_2.CellInfoCdma cic = ci.cdma.get(0); + mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma); + mCellSignalStrengthCdma = + new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo); + } + @Override public CellIdentityCdma getCellIdentity() { return mCellIdentityCdma; diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java index 7211de1798da..ad16dfae7295 100644 --- a/telephony/java/android/telephony/CellInfoGsm.java +++ b/telephony/java/android/telephony/CellInfoGsm.java @@ -43,8 +43,24 @@ public final class CellInfoGsm extends CellInfo implements Parcelable { /** @hide */ public CellInfoGsm(CellInfoGsm ci) { super(ci); - this.mCellIdentityGsm = ci.mCellIdentityGsm.copy(); - this.mCellSignalStrengthGsm = ci.mCellSignalStrengthGsm.copy(); + mCellIdentityGsm = ci.mCellIdentityGsm.copy(); + mCellSignalStrengthGsm = ci.mCellSignalStrengthGsm.copy(); + } + + /** @hide */ + public CellInfoGsm(android.hardware.radio.V1_0.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_0.CellInfoGsm cig = ci.gsm.get(0); + mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm); + mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm); + } + + /** @hide */ + public CellInfoGsm(android.hardware.radio.V1_2.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_2.CellInfoGsm cig = ci.gsm.get(0); + mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm); + mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm); } @Override diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java index 7d5388b7b7f4..75938317bf44 100644 --- a/telephony/java/android/telephony/CellInfoLte.java +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -51,13 +52,31 @@ public final class CellInfoLte extends CellInfo implements Parcelable { this.mCellConfig = new CellConfigLte(ci.mCellConfig); } + /** @hide */ + public CellInfoLte(android.hardware.radio.V1_0.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_0.CellInfoLte cil = ci.lte.get(0); + mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte); + mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte); + mCellConfig = new CellConfigLte(); + } + + /** @hide */ + public CellInfoLte(android.hardware.radio.V1_2.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_2.CellInfoLte cil = ci.lte.get(0); + mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte); + mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte); + mCellConfig = new CellConfigLte(); + } + @Override public CellIdentityLte getCellIdentity() { if (DBG) log("getCellIdentity: " + mCellIdentityLte); return mCellIdentityLte; } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCellIdentity(CellIdentityLte cid) { if (DBG) log("setCellIdentity: " + cid); mCellIdentityLte = cid; @@ -69,7 +88,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { return mCellSignalStrengthLte; } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCellSignalStrength(CellSignalStrengthLte css) { if (DBG) log("setCellSignalStrength: " + css); mCellSignalStrengthLte = css; diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java index 40cadde364dc..a8c49b7bf68e 100644 --- a/telephony/java/android/telephony/CellInfoTdscdma.java +++ b/telephony/java/android/telephony/CellInfoTdscdma.java @@ -48,8 +48,23 @@ public final class CellInfoTdscdma extends CellInfo implements Parcelable { this.mCellSignalStrengthTdscdma = ci.mCellSignalStrengthTdscdma.copy(); } - @Override - public CellIdentityTdscdma getCellIdentity() { + /** @hide */ + public CellInfoTdscdma(android.hardware.radio.V1_0.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_0.CellInfoTdscdma cit = ci.tdscdma.get(0); + mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma); + mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma); + } + + /** @hide */ + public CellInfoTdscdma(android.hardware.radio.V1_2.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_2.CellInfoTdscdma cit = ci.tdscdma.get(0); + mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma); + mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma); + } + + @Override public CellIdentityTdscdma getCellIdentity() { return mCellIdentityTdscdma; } /** @hide */ diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java index 4f9dcb1a0637..a427e80fd65c 100644 --- a/telephony/java/android/telephony/CellInfoWcdma.java +++ b/telephony/java/android/telephony/CellInfoWcdma.java @@ -47,6 +47,22 @@ public final class CellInfoWcdma extends CellInfo implements Parcelable { this.mCellSignalStrengthWcdma = ci.mCellSignalStrengthWcdma.copy(); } + /** @hide */ + public CellInfoWcdma(android.hardware.radio.V1_0.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_0.CellInfoWcdma ciw = ci.wcdma.get(0); + mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma); + mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma); + } + + /** @hide */ + public CellInfoWcdma(android.hardware.radio.V1_2.CellInfo ci) { + super(ci); + final android.hardware.radio.V1_2.CellInfoWcdma ciw = ci.wcdma.get(0); + mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma); + mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma); + } + @Override public CellIdentityWcdma getCellIdentity() { return mCellIdentityWcdma; diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java index fd21d42b1e9b..f2c14a147230 100644 --- a/telephony/java/android/telephony/CellSignalStrength.java +++ b/telephony/java/android/telephony/CellSignalStrength.java @@ -16,6 +16,8 @@ package android.telephony; +import android.os.PersistableBundle; + /** * Abstract base class for cell phone signal strength related information. */ @@ -80,9 +82,74 @@ public abstract class CellSignalStrength { */ public abstract CellSignalStrength copy(); + /** + * Checks and returns whether there are any non-default values in this CellSignalStrength. + * + * Checks all the values in the subclass of CellSignalStrength and returns true if any of them + * have been set to a value other than their default. + * + * @hide + */ + public abstract boolean isValid(); + @Override public abstract int hashCode(); @Override public abstract boolean equals (Object o); + + /** + * Calculate and set the carrier-influenced values such as the signal "Level". + * + * @hide + */ + public abstract void updateLevel(PersistableBundle cc, ServiceState ss); + + // Range for RSSI in ASU (0-31, 99) as defined in TS 27.007 8.69 + /** @hide */ + protected static final int getRssiDbmFromAsu(int asu) { + if (asu > 31 || asu < 0) return CellInfo.UNAVAILABLE; + return -113 + (2 * asu); + } + + // Range for RSSI in ASU (0-31, 99) as defined in TS 27.007 8.69 + /** @hide */ + protected static final int getAsuFromRssiDbm(int dbm) { + if (dbm == CellInfo.UNAVAILABLE) return 99; + return (dbm / 2) + 113; + } + + // Range for RSCP in ASU (0-96, 255) as defined in TS 27.007 8.69 + /** @hide */ + protected static final int getRscpDbmFromAsu(int asu) { + if (asu > 96 || asu < 0) return CellInfo.UNAVAILABLE; + return asu - 120; + } + + // Range for RSCP in ASU (0-96, 255) as defined in TS 27.007 8.69 + /** @hide */ + protected static final int getAsuFromRscpDbm(int dbm) { + if (dbm == CellInfo.UNAVAILABLE) return 255; + return dbm + 120; + } + + // Range for SNR in ASU (0-49, 255) as defined in TS 27.007 8.69 + /** @hide */ + protected static final int getEcNoDbFromAsu(int asu) { + if (asu > 49 || asu < 0) return CellInfo.UNAVAILABLE; + return -24 + (asu / 2); + } + + /** @hide */ + protected static final int inRangeOrUnavailable(int value, int rangeMin, int rangeMax) { + if (value < rangeMin || value > rangeMax) return CellInfo.UNAVAILABLE; + return value; + } + + /** @hide */ + protected static final int inRangeOrUnavailable( + int value, int rangeMin, int rangeMax, int special) { + if ((value < rangeMin || value > rangeMax) && value != special) return CellInfo.UNAVAILABLE; + return value; + } } diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java index 5123052cb78b..47faf1e96aac 100644 --- a/telephony/java/android/telephony/CellSignalStrengthCdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java @@ -18,6 +18,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import android.telephony.Rlog; import java.util.Objects; @@ -35,6 +36,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements private int mEvdoDbm; // This value is the EVDO RSSI value private int mEvdoEcio; // This value is the EVDO Ec/Io private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio + private int mLevel; /** @hide */ public CellSignalStrengthCdma() { @@ -55,23 +57,29 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements * rather than left as -1, which is a departure from SignalStrength, which is stuck with the * values it currently reports. * - * @param cdmaDbm negative of the CDMA signal strength value or -1 if invalid. - * @param cdmaEcio negative of the CDMA pilot/noise ratio or -1 if invalid. - * @param evdoDbm negative of the EvDO signal strength value or -1 if invalid. - * @param evdoEcio negative of the EvDO pilot/noise ratio or -1 if invalid. - * @param evdoSnr an SNR value 0..8 or -1 if invalid. + * @param cdmaDbm CDMA signal strength value or CellInfo.UNAVAILABLE if invalid. + * @param cdmaEcio CDMA pilot/noise ratio or CellInfo.UNAVAILABLE if invalid. + * @param evdoDbm negative of the EvDO signal strength value or CellInfo.UNAVAILABLE if invalid. + * @param evdoEcio negative of the EvDO pilot/noise ratio or CellInfo.UNAVAILABLE if invalid. + * @param evdoSnr an SNR value 0..8 or CellInfo.UNVAILABLE if invalid. * @hide */ public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr) { - // The values here were lifted from SignalStrength.validateInput() - // FIXME: Combine all checking and setting logic between this and SignalStrength. - mCdmaDbm = ((cdmaDbm > 0) && (cdmaDbm < 120)) ? -cdmaDbm : CellInfo.UNAVAILABLE; - mCdmaEcio = ((cdmaEcio > 0) && (cdmaEcio < 160)) ? -cdmaEcio : CellInfo.UNAVAILABLE; + mCdmaDbm = inRangeOrUnavailable(cdmaDbm, -120, 0); + mCdmaEcio = inRangeOrUnavailable(cdmaEcio, -160, 0); + mEvdoDbm = inRangeOrUnavailable(evdoDbm, -120, 0); + mEvdoEcio = inRangeOrUnavailable(evdoEcio, -160, 0); + mEvdoSnr = inRangeOrUnavailable(evdoSnr, 0, 8); - mEvdoDbm = ((evdoDbm > 0) && (evdoDbm < 120)) ? -evdoDbm : CellInfo.UNAVAILABLE; - mEvdoEcio = ((evdoEcio > 0) && (evdoEcio < 160)) ? -evdoEcio : CellInfo.UNAVAILABLE; - mEvdoSnr = ((evdoSnr > 0) && (evdoSnr <= 8)) ? evdoSnr : CellInfo.UNAVAILABLE; + updateLevel(null, null); + } + + /** @hide */ + public CellSignalStrengthCdma(android.hardware.radio.V1_0.CdmaSignalStrength cdma, + android.hardware.radio.V1_0.EvdoSignalStrength evdo) { + // Convert from HAL values as part of construction. + this(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio, evdo.signalNoiseRatio); } /** @hide */ @@ -86,6 +94,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements mEvdoDbm = s.mEvdoDbm; mEvdoEcio = s.mEvdoEcio; mEvdoSnr = s.mEvdoSnr; + mLevel = s.mLevel; } /** @hide */ @@ -102,6 +111,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements mEvdoDbm = CellInfo.UNAVAILABLE; mEvdoEcio = CellInfo.UNAVAILABLE; mEvdoSnr = CellInfo.UNAVAILABLE; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } /** @@ -112,26 +122,54 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements */ @Override public int getLevel() { - int level; + return mLevel; + } + /** @hide */ + @Override + public void updateLevel(PersistableBundle cc, ServiceState ss) { int cdmaLevel = getCdmaLevel(); int evdoLevel = getEvdoLevel(); if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { /* We don't know evdo, use cdma */ - level = getCdmaLevel(); + mLevel = getCdmaLevel(); } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { /* We don't know cdma, use evdo */ - level = getEvdoLevel(); + mLevel = getEvdoLevel(); } else { /* We know both, use the lowest level */ - level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; + mLevel = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; } - if (DBG) log("getLevel=" + level); - return level; } /** - * Get the signal level as an asu value between 0..97, 99 is unknown + * Get the 1xRTT Level in (Android) ASU. + * + * There is no standard definition of ASU for CDMA; however, Android defines it as the + * the lesser of the following two results (for 1xRTT): + * <table> + * <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead> + * <tbody> + * <tr><td>-75..</td><td>16</td></tr> + * <tr><td>-82..-76</td><td>8</td></tr> + * <tr><td>-90..-83</td><td>4</td></tr> + * <tr><td>-95..-91</td><td>2</td></tr> + * <tr><td>-100..-96</td><td>1</td></tr> + * <tr><td>..-101</td><td>99</td></tr> + * </tbody> + * </table> + * <table> + * <thead><tr><th>Ec/Io Range (dB)</th><th>ASU Value</th></tr><thead> + * <tbody> + * <tr><td>-90..</td><td>16</td></tr> + * <tr><td>-100..-91</td><td>8</td></tr> + * <tr><td>-115..-101</td><td>4</td></tr> + * <tr><td>-130..-116</td><td>2</td></tr> + * <tr><td>--150..-131</td><td>1</td></tr> + * <tr><td>..-151</td><td>99</td></tr> + * </tbody> + * </table> + * @return 1xRTT Level in Android ASU {1,2,4,8,16,99} */ @Override public int getAsuLevel() { @@ -220,6 +258,63 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements } /** + * Get the EVDO Level in (Android) ASU. + * + * There is no standard definition of ASU for CDMA; however, Android defines it as the + * the lesser of the following two results (for EVDO): + * <table> + * <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead> + * <tbody> + * <tr><td>-65..</td><td>16</td></tr> + * <tr><td>-75..-66</td><td>8</td></tr> + * <tr><td>-85..-76</td><td>4</td></tr> + * <tr><td>-95..-86</td><td>2</td></tr> + * <tr><td>-105..-96</td><td>1</td></tr> + * <tr><td>..-106</td><td>99</td></tr> + * </tbody> + * </table> + * <table> + * <thead><tr><th>SNR Range (unitless)</th><th>ASU Value</th></tr><thead> + * <tbody> + * <tr><td>7..</td><td>16</td></tr> + * <tr><td>6</td><td>8</td></tr> + * <tr><td>5</td><td>4</td></tr> + * <tr><td>3..4</td><td>2</td></tr> + * <tr><td>1..2</td><td>1</td></tr> + * <tr><td>0</td><td>99</td></tr> + * </tbody> + * </table> + * + * @return EVDO Level in Android ASU {1,2,4,8,16,99} + * + * @hide + */ + public int getEvdoAsuLevel() { + int evdoDbm = getEvdoDbm(); + int evdoSnr = getEvdoSnr(); + int levelEvdoDbm; + int levelEvdoSnr; + + if (evdoDbm >= -65) levelEvdoDbm = 16; + else if (evdoDbm >= -75) levelEvdoDbm = 8; + else if (evdoDbm >= -85) levelEvdoDbm = 4; + else if (evdoDbm >= -95) levelEvdoDbm = 2; + else if (evdoDbm >= -105) levelEvdoDbm = 1; + else levelEvdoDbm = 99; + + if (evdoSnr >= 7) levelEvdoSnr = 16; + else if (evdoSnr >= 6) levelEvdoSnr = 8; + else if (evdoSnr >= 5) levelEvdoSnr = 4; + else if (evdoSnr >= 3) levelEvdoSnr = 2; + else if (evdoSnr >= 1) levelEvdoSnr = 1; + else levelEvdoSnr = 99; + + int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; + if (DBG) log("getEvdoAsuLevel=" + level); + return level; + } + + /** * Get the signal strength as dBm */ @Override @@ -237,6 +332,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getCdmaDbm() { return mCdmaDbm; } + /** @hide */ public void setCdmaDbm(int cdmaDbm) { mCdmaDbm = cdmaDbm; @@ -248,6 +344,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getCdmaEcio() { return mCdmaEcio; } + /** @hide */ public void setCdmaEcio(int cdmaEcio) { mCdmaEcio = cdmaEcio; @@ -259,6 +356,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getEvdoDbm() { return mEvdoDbm; } + /** @hide */ public void setEvdoDbm(int evdoDbm) { mEvdoDbm = evdoDbm; @@ -270,6 +368,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getEvdoEcio() { return mEvdoEcio; } + /** @hide */ public void setEvdoEcio(int evdoEcio) { mEvdoEcio = evdoEcio; @@ -281,6 +380,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getEvdoSnr() { return mEvdoSnr; } + /** @hide */ public void setEvdoSnr(int evdoSnr) { mEvdoSnr = evdoSnr; @@ -288,28 +388,29 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements @Override public int hashCode() { - return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr); + return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr, mLevel); + } + + private static final CellSignalStrengthCdma sInvalid = new CellSignalStrengthCdma(); + + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); } @Override public boolean equals (Object o) { CellSignalStrengthCdma s; - - try { - s = (CellSignalStrengthCdma) o; - } catch (ClassCastException ex) { - return false; - } - - if (o == null) { - return false; - } + if (!(o instanceof CellSignalStrengthCdma)) return false; + s = (CellSignalStrengthCdma) o; return mCdmaDbm == s.mCdmaDbm && mCdmaEcio == s.mCdmaEcio && mEvdoDbm == s.mEvdoDbm && mEvdoEcio == s.mEvdoEcio - && mEvdoSnr == s.mEvdoSnr; + && mEvdoSnr == s.mEvdoSnr + && mLevel == s.mLevel; } /** @@ -322,7 +423,8 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements + " cdmaEcio=" + mCdmaEcio + " evdoDbm=" + mEvdoDbm + " evdoEcio=" + mEvdoEcio - + " evdoSnr=" + mEvdoSnr; + + " evdoSnr=" + mEvdoSnr + + " level=" + mLevel; } /** Implement the Parcelable interface */ @@ -334,6 +436,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements dest.writeInt(mEvdoDbm); dest.writeInt(mEvdoEcio); dest.writeInt(mEvdoSnr); + dest.writeInt(mLevel); } /** @@ -349,6 +452,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements mEvdoDbm = in.readInt(); mEvdoEcio = in.readInt(); mEvdoSnr = in.readInt(); + mLevel = in.readInt(); if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java index e906f460024a..7b29f69da6da 100644 --- a/telephony/java/android/telephony/CellSignalStrengthGsm.java +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -19,6 +19,7 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import android.telephony.Rlog; import java.util.Objects; @@ -31,16 +32,18 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P private static final String LOG_TAG = "CellSignalStrengthGsm"; private static final boolean DBG = false; - private static final int GSM_SIGNAL_STRENGTH_GREAT = 12; - private static final int GSM_SIGNAL_STRENGTH_GOOD = 8; - private static final int GSM_SIGNAL_STRENGTH_MODERATE = 5; + private static final int GSM_RSSI_MAX = -51; + private static final int GSM_RSSI_GREAT = -89; + private static final int GSM_RSSI_GOOD = -97; + private static final int GSM_RSSI_MODERATE = -103; + private static final int GSM_RSSI_POOR = -107; + private int mRssi; // in dBm [-113, -51] or UNAVAILABLE @UnsupportedAppUsage - private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5 - @UnsupportedAppUsage - private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 - @UnsupportedAppUsage + private int mBitErrorRate; // bit error rate (0-7, 99) TS 27.007 8.5 or UNAVAILABLE + @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O) private int mTimingAdvance; // range from 0-219 or CellInfo.UNAVAILABLE if unknown + private int mLevel; /** @hide */ @UnsupportedAppUsage @@ -49,15 +52,17 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P } /** @hide */ - public CellSignalStrengthGsm(int ss, int ber) { - this(ss, ber, CellInfo.UNAVAILABLE); + public CellSignalStrengthGsm(int rssi, int ber, int ta) { + mRssi = inRangeOrUnavailable(rssi, -113, -51); + mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99); + mTimingAdvance = inRangeOrUnavailable(ta, 0, 219); + updateLevel(null, null); } /** @hide */ - public CellSignalStrengthGsm(int ss, int ber, int ta) { - mSignalStrength = ss; - mBitErrorRate = ber; - mTimingAdvance = ta; + public CellSignalStrengthGsm(android.hardware.radio.V1_0.GsmSignalStrength gsm) { + // Convert from HAL values as part of construction. + this(getRssiDbmFromAsu(gsm.signalStrength), gsm.bitErrorRate, gsm.timingAdvance); } /** @hide */ @@ -67,9 +72,10 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P /** @hide */ protected void copyFrom(CellSignalStrengthGsm s) { - mSignalStrength = s.mSignalStrength; + mRssi = s.mRssi; mBitErrorRate = s.mBitErrorRate; mTimingAdvance = s.mTimingAdvance; + mLevel = s.mLevel; } /** @hide */ @@ -81,9 +87,10 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P /** @hide */ @Override public void setDefaultValues() { - mSignalStrength = CellInfo.UNAVAILABLE; + mRssi = CellInfo.UNAVAILABLE; mBitErrorRate = CellInfo.UNAVAILABLE; mTimingAdvance = CellInfo.UNAVAILABLE; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } /** @@ -94,20 +101,18 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P */ @Override public int getLevel() { - int level; - - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int asu = mSignalStrength; - if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - else if (asu >= GSM_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT; - else if (asu >= GSM_SIGNAL_STRENGTH_GOOD) level = SIGNAL_STRENGTH_GOOD; - else if (asu >= GSM_SIGNAL_STRENGTH_MODERATE) level = SIGNAL_STRENGTH_MODERATE; - else level = SIGNAL_STRENGTH_POOR; - if (DBG) log("getLevel=" + level); - return level; + return mLevel; + } + + /** @hide */ + @Override + public void updateLevel(PersistableBundle cc, ServiceState ss) { + if (mRssi > GSM_RSSI_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + else if (mRssi >= GSM_RSSI_GREAT) mLevel = SIGNAL_STRENGTH_GREAT; + else if (mRssi >= GSM_RSSI_GOOD) mLevel = SIGNAL_STRENGTH_GOOD; + else if (mRssi >= GSM_RSSI_MODERATE) mLevel = SIGNAL_STRENGTH_MODERATE; + else if (mRssi >= GSM_RSSI_POOR) mLevel = SIGNAL_STRENGTH_POOR; + else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } /** @@ -126,55 +131,52 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P */ @Override public int getDbm() { - int dBm; - - int level = mSignalStrength; - int asu = (level == 99 ? CellInfo.UNAVAILABLE : level); - if (asu != CellInfo.UNAVAILABLE) { - dBm = -113 + (2 * asu); - } else { - dBm = CellInfo.UNAVAILABLE; - } - if (DBG) log("getDbm=" + dBm); - return dBm; + return mRssi; } /** - * Get the signal level as an asu value between 0..31, 99 is unknown + * Get the RSSI in ASU. + * * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @return RSSI in ASU 0..31, 99, or UNAVAILABLE */ @Override public int getAsuLevel() { - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int level = mSignalStrength; - if (DBG) log("getAsuLevel=" + level); - return level; + return getAsuFromRssiDbm(mRssi); + } + + /** + * Return the Bit Error Rate + * @returns the bit error rate (0-7, 99) as defined in TS 27.007 8.5 or UNAVAILABLE. + * @hide + */ + public int getBitErrorRate() { + return mBitErrorRate; } @Override public int hashCode() { - return Objects.hash(mSignalStrength, mBitErrorRate, mTimingAdvance); + return Objects.hash(mRssi, mBitErrorRate, mTimingAdvance); } - @Override - public boolean equals (Object o) { - CellSignalStrengthGsm s; + private static final CellSignalStrengthGsm sInvalid = new CellSignalStrengthGsm(); - try { - s = (CellSignalStrengthGsm) o; - } catch (ClassCastException ex) { - return false; - } + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); + } - if (o == null) { - return false; - } + @Override + public boolean equals(Object o) { + if (!(o instanceof CellSignalStrengthGsm)) return false; + CellSignalStrengthGsm s = (CellSignalStrengthGsm) o; - return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate && - s.mTimingAdvance == mTimingAdvance; + return mRssi == s.mRssi + && mBitErrorRate == s.mBitErrorRate + && mTimingAdvance == s.mTimingAdvance + && mLevel == s.mLevel; } /** @@ -183,18 +185,20 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P @Override public String toString() { return "CellSignalStrengthGsm:" - + " ss=" + mSignalStrength + + " rssi=" + mRssi + " ber=" + mBitErrorRate - + " mTa=" + mTimingAdvance; + + " mTa=" + mTimingAdvance + + " mLevel=" + mLevel; } /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { if (DBG) log("writeToParcel(Parcel, int): " + toString()); - dest.writeInt(mSignalStrength); + dest.writeInt(mRssi); dest.writeInt(mBitErrorRate); dest.writeInt(mTimingAdvance); + dest.writeInt(mLevel); } /** @@ -202,9 +206,10 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P * where the token is already been processed. */ private CellSignalStrengthGsm(Parcel in) { - mSignalStrength = in.readInt(); + mRssi = in.readInt(); mBitErrorRate = in.readInt(); mTimingAdvance = in.readInt(); + mLevel = in.readInt(); if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java index d07539431348..893dbe31ce0b 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -19,7 +19,9 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; +import java.util.Arrays; import java.util.Objects; /** @@ -28,7 +30,7 @@ import java.util.Objects; public final class CellSignalStrengthLte extends CellSignalStrength implements Parcelable { private static final String LOG_TAG = "CellSignalStrengthLte"; - private static final boolean DBG = false; + private static final boolean DBG = true; /** * Indicates the unknown or undetectable RSSI value in ASU. @@ -49,18 +51,23 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P */ private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0; - @UnsupportedAppUsage - private int mSignalStrength; - @UnsupportedAppUsage + private static final int MAX_LTE_RSRP = -44; + private static final int MIN_LTE_RSRP = -140; + + @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P) + private int mSignalStrength; // To be removed + private int mRssi; + @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O) private int mRsrp; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O) private int mRsrq; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O) private int mRssnr; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O) private int mCqi; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O) private int mTimingAdvance; + private int mLevel; /** @hide */ @UnsupportedAppUsage @@ -68,15 +75,38 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P setDefaultValues(); } + /** + * Construct a cell signal strength + * + * @param rssi in dBm [-113,-51], UNKNOWN + * @param rsrp in dBm [-140,-43], UNKNOWN + * @param rsrq in dB [-20,-3], UNKNOWN + * @param rssnr in 10*dB [-200, +300], UNKNOWN + * @param cqi [0, 15], UNKNOWN + * @param timingAdvance [0, 1282], UNKNOWN + * + */ /** @hide */ - public CellSignalStrengthLte(int signalStrength, int rsrp, int rsrq, int rssnr, int cqi, + public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi, int timingAdvance) { - mSignalStrength = signalStrength; - mRsrp = rsrp; - mRsrq = rsrq; - mRssnr = rssnr; - mCqi = cqi; - mTimingAdvance = timingAdvance; + + mRssi = inRangeOrUnavailable(rssi, -113, -51); + mSignalStrength = mRssi; + mRsrp = inRangeOrUnavailable(rsrp, -140, -43); + mRsrq = inRangeOrUnavailable(rsrq, -20, -3); + mRssnr = inRangeOrUnavailable(rssnr, -200, 300); + mCqi = inRangeOrUnavailable(cqi, 0, 15); + mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282); + updateLevel(null, null); + } + + /** @hide */ + public CellSignalStrengthLte(android.hardware.radio.V1_0.LteSignalStrength lte) { + // Convert from HAL values as part of construction. + this(convertRssiAsuToDBm(lte.signalStrength), + lte.rsrp != CellInfo.UNAVAILABLE ? -lte.rsrp : lte.rsrp, + lte.rsrq != CellInfo.UNAVAILABLE ? -lte.rsrq : lte.rsrq, + lte.rssnr, lte.cqi, lte.timingAdvance); } /** @hide */ @@ -87,11 +117,13 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** @hide */ protected void copyFrom(CellSignalStrengthLte s) { mSignalStrength = s.mSignalStrength; + mRssi = s.mRssi; mRsrp = s.mRsrp; mRsrq = s.mRsrq; mRssnr = s.mRssnr; mCqi = s.mCqi; mTimingAdvance = s.mTimingAdvance; + mLevel = s.mLevel; } /** @hide */ @@ -104,11 +136,13 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P @Override public void setDefaultValues() { mSignalStrength = CellInfo.UNAVAILABLE; + mRssi = CellInfo.UNAVAILABLE; mRsrp = CellInfo.UNAVAILABLE; mRsrq = CellInfo.UNAVAILABLE; mRssnr = CellInfo.UNAVAILABLE; mCqi = CellInfo.UNAVAILABLE; mTimingAdvance = CellInfo.UNAVAILABLE; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } /** @@ -119,34 +153,106 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P */ @Override public int getLevel() { - int levelRsrp = 0; - int levelRssnr = 0; - - if (mRsrp == CellInfo.UNAVAILABLE) levelRsrp = 0; - else if (mRsrp >= -95) levelRsrp = SIGNAL_STRENGTH_GREAT; - else if (mRsrp >= -105) levelRsrp = SIGNAL_STRENGTH_GOOD; - else if (mRsrp >= -115) levelRsrp = SIGNAL_STRENGTH_MODERATE; - else levelRsrp = SIGNAL_STRENGTH_POOR; - - // See RIL_LTE_SignalStrength in ril.h - if (mRssnr == CellInfo.UNAVAILABLE) levelRssnr = 0; - else if (mRssnr >= 45) levelRssnr = SIGNAL_STRENGTH_GREAT; - else if (mRssnr >= 10) levelRssnr = SIGNAL_STRENGTH_GOOD; - else if (mRssnr >= -30) levelRssnr = SIGNAL_STRENGTH_MODERATE; - else levelRssnr = SIGNAL_STRENGTH_POOR; - - int level; - if (mRsrp == CellInfo.UNAVAILABLE) { - level = levelRssnr; - } else if (mRssnr == CellInfo.UNAVAILABLE) { - level = levelRsrp; + return mLevel; + } + + // Lifted from Default carrier configs and max range of RSRP + private static final int[] sThresholds = new int[]{-115, -105, -95, -85}; + private static final int sRsrpBoost = 0; + + /** @hide */ + @Override + public void updateLevel(PersistableBundle cc, ServiceState ss) { + int[] thresholds; + boolean rsrpOnly; + if (cc == null) { + thresholds = sThresholds; + rsrpOnly = false; + } else { + rsrpOnly = cc.getBoolean( + CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false); + thresholds = cc.getIntArray( + CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY); + if (thresholds == null) thresholds = sThresholds; + if (DBG) log("updateLevel() carrierconfig - rsrpOnly=" + + rsrpOnly + ", thresholds=" + Arrays.toString(thresholds)); + } + + + int rsrpBoost = 0; + if (ss != null) { + rsrpBoost = ss.getLteEarfcnRsrpBoost(); + } + + int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + int rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + int snrIconLevel = -1; + + int rsrp = mRsrp + rsrpBoost; + + if (rsrp < MIN_LTE_RSRP || rsrp > MAX_LTE_RSRP) { + rsrpIconLevel = -1; } else { - level = (levelRssnr < levelRsrp) ? levelRssnr : levelRsrp; + rsrpIconLevel = thresholds.length; + while (rsrpIconLevel > 0 && rsrp < thresholds[rsrpIconLevel - 1]) rsrpIconLevel--; + } + + if (rsrpOnly) { + if (DBG) log("updateLevel() - rsrp = " + rsrpIconLevel); + if (rsrpIconLevel != -1) { + mLevel = rsrpIconLevel; + return; + } } - if (DBG) log("Lte rsrp level: " + levelRsrp - + " snr level: " + levelRssnr + " level: " + level); - return level; + /* + * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 + * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars + * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna + * Icon Only + */ + if (mRssnr > 300) snrIconLevel = -1; + else if (mRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; + else if (mRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; + else if (mRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; + else if (mRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; + else if (mRssnr >= -200) + snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + + if (DBG) log("updateLevel() - rsrp:" + mRsrp + " snr:" + mRssnr + " rsrpIconLevel:" + + rsrpIconLevel + " snrIconLevel:" + snrIconLevel + + " lteRsrpBoost:" + sRsrpBoost); + + /* Choose a measurement type to use for notification */ + if (snrIconLevel != -1 && rsrpIconLevel != -1) { + /* + * The number of bars displayed shall be the smaller of the bars + * associated with LTE RSRP and the bars associated with the LTE + * RS_SNR + */ + mLevel = (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); + return; + } + + if (snrIconLevel != -1) { + mLevel = snrIconLevel; + return; + } + + if (rsrpIconLevel != -1) { + mLevel = rsrpIconLevel; + return; + } + + if (mRssi > -51) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + else if (mRssi >= -89) rssiIconLevel = SIGNAL_STRENGTH_GREAT; + else if (mRssi >= -97) rssiIconLevel = SIGNAL_STRENGTH_GOOD; + else if (mRssi >= -103) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; + else if (mRssi >= -113) rssiIconLevel = SIGNAL_STRENGTH_POOR; + else rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + if (DBG) log("getLteLevel - rssi:" + mRssi + " rssiIconLevel:" + + rssiIconLevel); + mLevel = rssiIconLevel; } /** @@ -169,7 +275,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable. */ public int getRssi() { - return convertRssiAsuToDBm(mSignalStrength); + return mRssi; } /** @@ -212,13 +318,16 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P } /** - * Get the LTE signal level as an asu value between 0..97, 99 is unknown + * Get the RSRP in ASU. + * * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @return RSCP in ASU 0..97, 255, or UNAVAILABLE */ @Override public int getAsuLevel() { int lteAsuLevel = 99; - int lteDbm = getDbm(); + int lteDbm = mRsrp; if (lteDbm == CellInfo.UNAVAILABLE) lteAsuLevel = 99; else if (lteDbm <= -140) lteAsuLevel = 0; else if (lteDbm >= -43) lteAsuLevel = 97; @@ -241,29 +350,31 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P @Override public int hashCode() { - return Objects.hash(mSignalStrength, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance); + return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance, mLevel); + } + + private static final CellSignalStrengthLte sInvalid = new CellSignalStrengthLte(); + + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); } @Override public boolean equals (Object o) { CellSignalStrengthLte s; - try { - s = (CellSignalStrengthLte) o; - } catch (ClassCastException ex) { - return false; - } - - if (o == null) { - return false; - } + if (!(o instanceof CellSignalStrengthLte)) return false; + s = (CellSignalStrengthLte) o; - return mSignalStrength == s.mSignalStrength + return mRssi == s.mRssi && mRsrp == s.mRsrp && mRsrq == s.mRsrq && mRssnr == s.mRssnr && mCqi == s.mCqi - && mTimingAdvance == s.mTimingAdvance; + && mTimingAdvance == s.mTimingAdvance + && mLevel == s.mLevel; } /** @@ -272,27 +383,29 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P @Override public String toString() { return "CellSignalStrengthLte:" - + " ss=" + mSignalStrength + + " rssi=" + mRssi + " rsrp=" + mRsrp + " rsrq=" + mRsrq + " rssnr=" + mRssnr + " cqi=" + mCqi - + " ta=" + mTimingAdvance; + + " ta=" + mTimingAdvance + + " level=" + mLevel; } /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { if (DBG) log("writeToParcel(Parcel, int): " + toString()); - dest.writeInt(mSignalStrength); + dest.writeInt(mRssi); // Need to multiply rsrp and rsrq by -1 // to ensure consistency when reading values written here // unless the values are invalid - dest.writeInt(mRsrp * (mRsrp != CellInfo.UNAVAILABLE ? -1 : 1)); - dest.writeInt(mRsrq * (mRsrq != CellInfo.UNAVAILABLE ? -1 : 1)); + dest.writeInt(mRsrp); + dest.writeInt(mRsrq); dest.writeInt(mRssnr); dest.writeInt(mCqi); dest.writeInt(mTimingAdvance); + dest.writeInt(mLevel); } /** @@ -300,16 +413,14 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P * where the token is already been processed. */ private CellSignalStrengthLte(Parcel in) { - mSignalStrength = in.readInt(); - // rsrp and rsrq are written into the parcel as positive values. - // Need to convert into negative values unless the values are invalid + mRssi = in.readInt(); + mSignalStrength = mRssi; mRsrp = in.readInt(); - if (mRsrp != CellInfo.UNAVAILABLE) mRsrp *= -1; mRsrq = in.readInt(); - if (mRsrq != CellInfo.UNAVAILABLE) mRsrq *= -1; mRssnr = in.readInt(); mCqi = in.readInt(); mTimingAdvance = in.readInt(); + mLevel = in.readInt(); if (DBG) log("CellSignalStrengthLte(Parcel): " + toString()); } @@ -342,13 +453,12 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P } private static int convertRssiAsuToDBm(int rssiAsu) { - if (rssiAsu != SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN - && (rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE - || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) { - Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu); + if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) { return CellInfo.UNAVAILABLE; } - if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) { + if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE + || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) { + Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu); return CellInfo.UNAVAILABLE; } return -113 + (2 * rssiAsu); diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java index 807924222a26..061cd4b33950 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -18,6 +18,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import java.util.Objects; @@ -48,6 +49,12 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa private int mSsRsrp; private int mSsRsrq; private int mSsSinr; + private int mLevel; + + /** @hide */ + public CellSignalStrengthNr() { + setDefaultValues(); + } /** * @param csiRsrp CSI reference signal received power. @@ -60,12 +67,13 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa */ public CellSignalStrengthNr( int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) { - mCsiRsrp = csiRsrp; - mCsiRsrq = csiRsrq; - mCsiSinr = csiSinr; - mSsRsrp = ssRsrp; - mSsRsrq = ssRsrq; - mSsSinr = ssSinr; + mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44); + mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3); + mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23); + mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44); + mSsRsrq = inRangeOrUnavailable(ssRsrq, -20, -3); + mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40); + updateLevel(null, null); } /** @@ -142,6 +150,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa dest.writeInt(mSsRsrp); dest.writeInt(mSsRsrq); dest.writeInt(mSsSinr); + dest.writeInt(mLevel); } private CellSignalStrengthNr(Parcel in) { @@ -151,6 +160,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa mSsRsrp = in.readInt(); mSsRsrq = in.readInt(); mSsSinr = in.readInt(); + mLevel = in.readInt(); } /** @hide */ @@ -162,27 +172,36 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa mSsRsrp = CellInfo.UNAVAILABLE; mSsRsrq = CellInfo.UNAVAILABLE; mSsSinr = CellInfo.UNAVAILABLE; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } @Override public int getLevel() { + return mLevel; + } + + /** @hide */ + @Override + public void updateLevel(PersistableBundle cc, ServiceState ss) { if (mCsiRsrp == CellInfo.UNAVAILABLE) { - return SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } else if (mCsiRsrp >= SIGNAL_GREAT_THRESHOLD) { - return SIGNAL_STRENGTH_GREAT; + mLevel = SIGNAL_STRENGTH_GREAT; } else if (mCsiRsrp >= SIGNAL_GOOD_THRESHOLD) { - return SIGNAL_STRENGTH_GOOD; + mLevel = SIGNAL_STRENGTH_GOOD; } else if (mCsiRsrp >= SIGNAL_MODERATE_THRESHOLD) { - return SIGNAL_STRENGTH_MODERATE; + mLevel = SIGNAL_STRENGTH_MODERATE; } else { - return SIGNAL_STRENGTH_POOR; + mLevel = SIGNAL_STRENGTH_POOR; } } /** - * Calculates the NR signal as an asu value between 0..97, 99 is unknown. - * Asu is calculated based on 3GPP RSRP, refer to 3GPP TS 27.007 section 8.69. - * @return an integer represent the asu level of the signal strength. + * Get the RSRP in ASU. + * + * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @return RSCP in ASU 0..97, 255, or UNAVAILABLE */ @Override public int getAsuLevel() { @@ -206,15 +225,33 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa } /** @hide */ + public CellSignalStrengthNr(CellSignalStrengthNr s) { + mCsiRsrp = s.mCsiRsrp; + mCsiRsrq = s.mCsiRsrq; + mCsiSinr = s.mCsiSinr; + mSsRsrp = s.mSsRsrp; + mSsRsrq = s.mSsRsrq; + mSsSinr = s.mSsSinr; + mLevel = s.mLevel; + } + + /** @hide */ @Override - public CellSignalStrength copy() { - return new CellSignalStrengthNr( - mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr); + public CellSignalStrengthNr copy() { + return new CellSignalStrengthNr(this); } @Override public int hashCode() { - return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr); + return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr, mLevel); + } + + private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr(); + + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); } @Override @@ -222,7 +259,8 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa if (obj instanceof CellSignalStrengthNr) { CellSignalStrengthNr o = (CellSignalStrengthNr) obj; return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr - && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr; + && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr + && mLevel == o.mLevel; } return false; } @@ -237,6 +275,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa .append(" ssRsrp = " + mSsRsrp) .append(" ssRsrq = " + mSsRsrq) .append(" ssSinr = " + mSsSinr) + .append(" level = " + mLevel) .append(" }") .toString(); } diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java index 4d040cca5fff..6f52b853d23b 100644 --- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java @@ -18,6 +18,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import java.util.Objects; @@ -31,27 +32,53 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen private static final String LOG_TAG = "CellSignalStrengthTdscdma"; private static final boolean DBG = false; - private static final int TDSCDMA_SIGNAL_STRENGTH_GREAT = 12; - private static final int TDSCDMA_SIGNAL_STRENGTH_GOOD = 8; - private static final int TDSCDMA_SIGNAL_STRENGTH_MODERATE = 5; + private static final int TDSCDMA_RSSI_MAX = -51; + private static final int TDSCDMA_RSSI_GREAT = -77; + private static final int TDSCDMA_RSSI_GOOD = -87; + private static final int TDSCDMA_RSSI_MODERATE = -97; + private static final int TDSCDMA_RSSI_POOR = -107; + + private static final int TDSCDMA_RSCP_MIN = -120; + private static final int TDSCDMA_RSCP_MAX = -24; + + private int mRssi; // in dBm [-113, -51], CellInfo.UNAVAILABLE - private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5 - // or CellInfo.UNAVAILABLE if unknown private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or // CellInfo.UNAVAILABLE if unknown - private int mRscp; // Pilot power (0-96, 255) as defined in TS 27.007 8.69 or + private int mRscp; // Pilot Power in dBm [-120, -24] or CellInfo.UNAVAILABLE // CellInfo.UNAVAILABLE if unknown + private int mLevel; + /** @hide */ public CellSignalStrengthTdscdma() { setDefaultValues(); } + /** + * @param rssi in dBm [-113, -51] or UNAVAILABLE + * @param ber [0-7], 99 or UNAVAILABLE + * @param rscp in dBm [-120, -24] or UNAVAILABLE + * @hide */ + public CellSignalStrengthTdscdma(int rssi, int ber, int rscp) { + mRssi = inRangeOrUnavailable(rssi, -113, -51); + mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99); + mRscp = inRangeOrUnavailable(rscp, -120, -24); + updateLevel(null, null); + } + /** @hide */ - public CellSignalStrengthTdscdma(int ss, int ber, int rscp) { - mSignalStrength = ss; - mBitErrorRate = ber; - mRscp = rscp; + public CellSignalStrengthTdscdma(android.hardware.radio.V1_0.TdScdmaSignalStrength tdscdma) { + // Convert from HAL values as part of construction. + this(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + tdscdma.rscp != CellInfo.UNAVAILABLE ? -tdscdma.rscp : tdscdma.rscp); + } + + /** @hide */ + public CellSignalStrengthTdscdma(android.hardware.radio.V1_2.TdscdmaSignalStrength tdscdma) { + // Convert from HAL values as part of construction. + this(getRssiDbmFromAsu(tdscdma.signalStrength), + tdscdma.bitErrorRate, getRscpDbmFromAsu(tdscdma.rscp)); } /** @hide */ @@ -61,9 +88,10 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen /** @hide */ protected void copyFrom(CellSignalStrengthTdscdma s) { - mSignalStrength = s.mSignalStrength; + mRssi = s.mRssi; mBitErrorRate = s.mBitErrorRate; mRscp = s.mRscp; + mLevel = s.mLevel; } /** @hide */ @@ -75,9 +103,10 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen /** @hide */ @Override public void setDefaultValues() { - mSignalStrength = CellInfo.UNAVAILABLE; + mRssi = CellInfo.UNAVAILABLE; mBitErrorRate = CellInfo.UNAVAILABLE; mRscp = CellInfo.UNAVAILABLE; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } /** @@ -88,26 +117,18 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen */ @Override public int getLevel() { - int level; - - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int asu = mSignalStrength; - if (asu <= 2 || asu == 99) { - level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GREAT) { - level = SIGNAL_STRENGTH_GREAT; - } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GOOD) { - level = SIGNAL_STRENGTH_GOOD; - } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_MODERATE) { - level = SIGNAL_STRENGTH_MODERATE; - } else { - level = SIGNAL_STRENGTH_POOR; - } - if (DBG) log("getLevel=" + level); - return level; + return mLevel; + } + + /** @hide */ + @Override + public void updateLevel(PersistableBundle cc, ServiceState ss) { + if (mRssi > TDSCDMA_RSSI_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + else if (mRssi >= TDSCDMA_RSSI_GREAT) mLevel = SIGNAL_STRENGTH_GREAT; + else if (mRssi >= TDSCDMA_RSSI_GOOD) mLevel = SIGNAL_STRENGTH_GOOD; + else if (mRssi >= TDSCDMA_RSSI_MODERATE) mLevel = SIGNAL_STRENGTH_MODERATE; + else if (mRssi >= TDSCDMA_RSSI_POOR) mLevel = SIGNAL_STRENGTH_POOR; + else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } /** @@ -115,56 +136,55 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen */ @Override public int getDbm() { - int dBm; - - int level = mSignalStrength; - int asu = (level == 99 ? CellInfo.UNAVAILABLE : level); - if (asu != CellInfo.UNAVAILABLE) { - dBm = -113 + (2 * asu); - } else { - dBm = CellInfo.UNAVAILABLE; - } - if (DBG) log("getDbm=" + dBm); - return dBm; + return mRscp; } /** - * Get the signal level as an asu value between 0..31, 99 is unknown + * Get the RSCP as dBm + * @hide + */ + public int getRscp() { + return mRscp; + } + + /** + * Get the RSCP in ASU. + * * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @return RSCP in ASU 0..96, 255, or UNAVAILABLE */ @Override public int getAsuLevel() { - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int level = mSignalStrength; - if (DBG) log("getAsuLevel=" + level); - return level; + if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp); + // For historical reasons, if RSCP is unavailable, this API will very incorrectly return + // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+ + if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi); + return getAsuFromRscpDbm(CellInfo.UNAVAILABLE); } @Override public int hashCode() { - return Objects.hash(mSignalStrength, mBitErrorRate); + return Objects.hash(mRssi, mBitErrorRate, mRscp, mLevel); } - @Override - public boolean equals(Object o) { - CellSignalStrengthTdscdma s; + private static final CellSignalStrengthTdscdma sInvalid = new CellSignalStrengthTdscdma(); - try { - s = (CellSignalStrengthTdscdma) o; - } catch (ClassCastException ex) { - return false; - } + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); + } - if (o == null) { - return false; - } + @Override + public boolean equals(Object o) { + if (!(o instanceof CellSignalStrengthTdscdma)) return false; + CellSignalStrengthTdscdma s = (CellSignalStrengthTdscdma) o; - return mSignalStrength == s.mSignalStrength + return mRssi == s.mRssi && mBitErrorRate == s.mBitErrorRate - && mRscp == s.mRscp; + && mRscp == s.mRscp + && mLevel == s.mLevel; } /** @@ -173,18 +193,20 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen @Override public String toString() { return "CellSignalStrengthTdscdma:" - + " ss=" + mSignalStrength + + " rssi=" + mRssi + " ber=" + mBitErrorRate - + " rscp=" + mRscp; + + " rscp=" + mRscp + + " level=" + mLevel; } /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { if (DBG) log("writeToParcel(Parcel, int): " + toString()); - dest.writeInt(mSignalStrength); + dest.writeInt(mRssi); dest.writeInt(mBitErrorRate); dest.writeInt(mRscp); + dest.writeInt(mLevel); } /** @@ -192,9 +214,10 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen * where the token is already been processed. */ private CellSignalStrengthTdscdma(Parcel in) { - mSignalStrength = in.readInt(); + mRssi = in.readInt(); mBitErrorRate = in.readInt(); mRscp = in.readInt(); + mLevel = in.readInt(); if (DBG) log("CellSignalStrengthTdscdma(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java index 0048cbdea8f6..88f6fbc4464d 100644 --- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java @@ -16,11 +16,14 @@ package android.telephony; -import android.annotation.UnsupportedAppUsage; +import android.annotation.StringDef; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import android.telephony.Rlog; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** @@ -31,20 +34,32 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements private static final String LOG_TAG = "CellSignalStrengthWcdma"; private static final boolean DBG = false; - private static final int WCDMA_SIGNAL_STRENGTH_GREAT = 12; - private static final int WCDMA_SIGNAL_STRENGTH_GOOD = 8; - private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5; + private static final int WCDMA_RSSI_MAX = -51; + private static final int WCDMA_RSSI_GREAT = -77; + private static final int WCDMA_RSSI_GOOD = -87; + private static final int WCDMA_RSSI_MODERATE = -97; + private static final int WCDMA_RSSI_POOR = -107; + private static final int WCDMA_RSSI_MIN = -113; - @UnsupportedAppUsage - private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5 - // or CellInfo.UNAVAILABLE if unknown - @UnsupportedAppUsage + private static final int WCDMA_RSCP_MIN = -120; + private static final int WCDMA_RSCP_MAX = -24; + + // TODO: Because these are used as values in CarrierConfig, they should be exposed somehow. + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @StringDef({LEVEL_CALCULATION_METHOD_RSSI, LEVEL_CALCULATION_METHOD_RSCP}) + public @interface LevelCalculationMethod {} + /** @hide */ + public static final String LEVEL_CALCULATION_METHOD_RSSI = "rssi"; + /** @hide */ + public static final String LEVEL_CALCULATION_METHOD_RSCP = "rscp"; + + private int mRssi; // in dBm [-113, 51] or CellInfo.UNAVAILABLE if unknown private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or // CellInfo.UNAVAILABLE if unknown - private int mRscp; // bit error rate (0-96, 255) as defined in TS 27.007 8.69 or - // CellInfo.UNAVAILABLE if unknown - private int mEcNo; // signal to noise radio (0-49, 255) as defined in TS 27.007 8.69 or - // CellInfo.UNAVAILABLE if unknown + private int mRscp; // in dBm [-120, -24] + private int mEcNo; // range -24, 1, CellInfo.UNAVAILABLE if unknown + private int mLevel; /** @hide */ public CellSignalStrengthWcdma() { @@ -52,11 +67,28 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements } /** @hide */ - public CellSignalStrengthWcdma(int ss, int ber, int rscp, int ecno) { - mSignalStrength = ss; - mBitErrorRate = ber; - mRscp = rscp; - mEcNo = ecno; + public CellSignalStrengthWcdma(int rssi, int ber, int rscp, int ecno) { + mRssi = inRangeOrUnavailable(rssi, WCDMA_RSSI_MIN, WCDMA_RSSI_MAX); + mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99); + mRscp = inRangeOrUnavailable(rscp, -120, -24); + mEcNo = inRangeOrUnavailable(ecno, -24, 1); + updateLevel(null, null); + } + + /** @hide */ + public CellSignalStrengthWcdma(android.hardware.radio.V1_0.WcdmaSignalStrength wcdma) { + // Convert from HAL values as part of construction. + this(getRssiDbmFromAsu(wcdma.signalStrength), + wcdma.bitErrorRate, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE); + } + + /** @hide */ + public CellSignalStrengthWcdma(android.hardware.radio.V1_2.WcdmaSignalStrength wcdma) { + // Convert from HAL values as part of construction. + this(getRssiDbmFromAsu(wcdma.base.signalStrength), + wcdma.base.bitErrorRate, + getRscpDbmFromAsu(wcdma.rscp), + getEcNoDbFromAsu(wcdma.ecno)); } /** @hide */ @@ -66,10 +98,11 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements /** @hide */ protected void copyFrom(CellSignalStrengthWcdma s) { - mSignalStrength = s.mSignalStrength; + mRssi = s.mRssi; mBitErrorRate = s.mBitErrorRate; mRscp = s.mRscp; mEcNo = s.mEcNo; + mLevel = s.mLevel; } /** @hide */ @@ -81,12 +114,17 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements /** @hide */ @Override public void setDefaultValues() { - mSignalStrength = CellInfo.UNAVAILABLE; + mRssi = CellInfo.UNAVAILABLE; mBitErrorRate = CellInfo.UNAVAILABLE; mRscp = CellInfo.UNAVAILABLE; mEcNo = CellInfo.UNAVAILABLE; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } + private static final String sLevelCalculationMethod = LEVEL_CALCULATION_METHOD_RSSI; + private static final int[] sThresholds = new int[]{ + WCDMA_RSSI_POOR, WCDMA_RSSI_GOOD, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT}; + /** * Retrieve an abstract level value for the overall signal strength. * @@ -95,20 +133,49 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements */ @Override public int getLevel() { - int level; - - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int asu = mSignalStrength; - if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - else if (asu >= WCDMA_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT; - else if (asu >= WCDMA_SIGNAL_STRENGTH_GOOD) level = SIGNAL_STRENGTH_GOOD; - else if (asu >= WCDMA_SIGNAL_STRENGTH_MODERATE) level = SIGNAL_STRENGTH_MODERATE; - else level = SIGNAL_STRENGTH_POOR; - if (DBG) log("getLevel=" + level); - return level; + return mLevel; + } + + /** @hide */ + @Override + public void updateLevel(PersistableBundle cc, ServiceState ss) { + String calcMethod; + int[] thresholds; + + if (cc == null) { + calcMethod = sLevelCalculationMethod; + thresholds = sThresholds; + } else { + // TODO: abstract this entire thing into a series of functions + calcMethod = cc.getString( + CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, + sLevelCalculationMethod); + thresholds = cc.getIntArray( + CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY); + if (thresholds == null) thresholds = sThresholds; + } + + int level = thresholds.length; + switch (calcMethod) { + case LEVEL_CALCULATION_METHOD_RSCP: + if (mRscp < WCDMA_RSCP_MIN || mRscp > WCDMA_RSCP_MAX) { + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + return; + } + while (level > 0 && mRscp < thresholds[level - 1]) level--; + mLevel = level; + return; + case LEVEL_CALCULATION_METHOD_RSSI: + if (mRssi < WCDMA_RSSI_MIN || mRssi > WCDMA_RSSI_MAX) { + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + return; + } + while (level > 0 && mRssi < thresholds[level - 1]) level--; + mLevel = level; + return; + default: + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + } } /** @@ -116,57 +183,66 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements */ @Override public int getDbm() { - int dBm; - - int level = mSignalStrength; - int asu = (level == 99 ? CellInfo.UNAVAILABLE : level); - if (asu != CellInfo.UNAVAILABLE) { - dBm = -113 + (2 * asu); - } else { - dBm = CellInfo.UNAVAILABLE; - } - if (DBG) log("getDbm=" + dBm); - return dBm; + if (mRscp != CellInfo.UNAVAILABLE) return mRscp; + return mRssi; } /** - * Get the signal level as an asu value between 0..31, 99 is unknown - * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * Get the RSCP in ASU. + * + * Asu is calculated based on 3GPP RSCP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @return RSCP in ASU 0..96, 255, or UNAVAILABLE */ @Override public int getAsuLevel() { - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int level = mSignalStrength; - if (DBG) log("getAsuLevel=" + level); - return level; + if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp); + // For historical reasons, if RSCP is unavailable, this API will very incorrectly return + // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+ + if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi); + return getAsuFromRscpDbm(CellInfo.UNAVAILABLE); + } + + /** + * Get the signal strength as dBm + * + * @hide + */ + public int getRssi() { + return mRssi; + } + + /** + * Get the RSCP as dBm + * @hide + */ + public int getRscp() { + return mRscp; } @Override public int hashCode() { - return Objects.hash(mSignalStrength, mBitErrorRate); + return Objects.hash(mRssi, mBitErrorRate, mRscp, mEcNo, mLevel); } - @Override - public boolean equals (Object o) { - CellSignalStrengthWcdma s; + private static final CellSignalStrengthWcdma sInvalid = new CellSignalStrengthWcdma(); - try { - s = (CellSignalStrengthWcdma) o; - } catch (ClassCastException ex) { - return false; - } + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); + } - if (o == null) { - return false; - } + @Override + public boolean equals(Object o) { + if (!(o instanceof CellSignalStrengthWcdma)) return false; + CellSignalStrengthWcdma s = (CellSignalStrengthWcdma) o; - return mSignalStrength == s.mSignalStrength + return mRssi == s.mRssi && mBitErrorRate == s.mBitErrorRate && mRscp == s.mRscp - && mEcNo == s.mEcNo; + && mEcNo == s.mEcNo + && mLevel == s.mLevel; } /** @@ -175,20 +251,22 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements @Override public String toString() { return "CellSignalStrengthWcdma:" - + " ss=" + mSignalStrength + + " ss=" + mRssi + " ber=" + mBitErrorRate + " rscp=" + mRscp - + " ecno=" + mEcNo; + + " ecno=" + mEcNo + + " level=" + mLevel; } /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { if (DBG) log("writeToParcel(Parcel, int): " + toString()); - dest.writeInt(mSignalStrength); + dest.writeInt(mRssi); dest.writeInt(mBitErrorRate); dest.writeInt(mRscp); dest.writeInt(mEcNo); + dest.writeInt(mLevel); } /** @@ -196,10 +274,11 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements * where the token is already been processed. */ private CellSignalStrengthWcdma(Parcel in) { - mSignalStrength = in.readInt(); + mRssi = in.readInt(); mBitErrorRate = in.readInt(); mRscp = in.readInt(); mEcNo = in.readInt(); + mLevel = in.readInt(); if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/ModemInfo.java b/telephony/java/android/telephony/ModemInfo.java index 564effe05e38..27a5121a148c 100644 --- a/telephony/java/android/telephony/ModemInfo.java +++ b/telephony/java/android/telephony/ModemInfo.java @@ -32,6 +32,11 @@ public class ModemInfo implements Parcelable { public final boolean isVoiceSupported; public final boolean isDataSupported; + // TODO b/121394331: Clean up this class after V1_1.PhoneCapability cleanup. + public ModemInfo(int modemId) { + this(modemId, 0, true, true); + } + public ModemInfo(int modemId, int rat, boolean isVoiceSupported, boolean isDataSupported) { this.modemId = modemId; this.rat = rat; diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java index ac38efb4d029..1c615aba8d61 100644 --- a/telephony/java/android/telephony/NeighboringCellInfo.java +++ b/telephony/java/android/telephony/NeighboringCellInfo.java @@ -25,6 +25,7 @@ import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS; import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -53,29 +54,29 @@ public class NeighboringCellInfo implements Parcelable * In GSM, mRssi is the Received RSSI; * In UMTS, mRssi is the Level index of CPICH Received Signal Code Power */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mRssi; /** * CID in 16 bits format in GSM. Return UNKNOWN_CID in UMTS and CMDA. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCid; /** * LAC in 16 bits format in GSM. Return UNKNOWN_CID in UMTS and CMDA. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mLac; /** * Primary Scrambling Code in 9 bits format in UMTS * Return UNKNOWN_CID in GSM and CMDA. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mPsc; /** * Radio network type, value is one of following * TelephonyManager.NETWORK_TYPE_XXXXXX. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mNetworkType; /** diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java index 448207424d59..0d94c4dd3686 100644 --- a/telephony/java/android/telephony/RadioAccessFamily.java +++ b/telephony/java/android/telephony/RadioAccessFamily.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -56,6 +57,9 @@ public class RadioAccessFamily implements Parcelable { public static final int RAF_LTE = TelephonyManager.NETWORK_TYPE_BITMASK_LTE; public static final int RAF_LTE_CA = TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA; + // 5G + public static final int RAF_NR = TelephonyManager.NETWORK_TYPE_BITMASK_NR; + // Grouping of RAFs // 2G private static final int GSM = RAF_GSM | RAF_GPRS | RAF_EDGE; @@ -67,6 +71,9 @@ public class RadioAccessFamily implements Parcelable { // 4G private static final int LTE = RAF_LTE | RAF_LTE_CA; + // 5G + private static final int NR = RAF_NR; + /* Phone ID of phone */ private int mPhoneId; @@ -159,84 +166,78 @@ public class RadioAccessFamily implements Parcelable { @UnsupportedAppUsage public static int getRafFromNetworkType(int type) { - int raf; - switch (type) { case RILConstants.NETWORK_MODE_WCDMA_PREF: - raf = GSM | WCDMA; - break; + return GSM | WCDMA; case RILConstants.NETWORK_MODE_GSM_ONLY: - raf = GSM; - break; + return GSM; case RILConstants.NETWORK_MODE_WCDMA_ONLY: - raf = WCDMA; - break; + return WCDMA; case RILConstants.NETWORK_MODE_GSM_UMTS: - raf = GSM | WCDMA; - break; + return GSM | WCDMA; case RILConstants.NETWORK_MODE_CDMA: - raf = CDMA | EVDO; - break; + return CDMA | EVDO; case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO: - raf = LTE | CDMA | EVDO; - break; + return LTE | CDMA | EVDO; case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA: - raf = LTE | GSM | WCDMA; - break; + return LTE | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: - raf = LTE | CDMA | EVDO | GSM | WCDMA; - break; + return LTE | CDMA | EVDO | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_ONLY: - raf = LTE; - break; + return LTE; case RILConstants.NETWORK_MODE_LTE_WCDMA: - raf = LTE | WCDMA; - break; + return LTE | WCDMA; case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: - raf = CDMA; - break; + return CDMA; case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: - raf = EVDO; - break; + return EVDO; case RILConstants.NETWORK_MODE_GLOBAL: - raf = GSM | WCDMA | CDMA | EVDO; - break; + return GSM | WCDMA | CDMA | EVDO; case RILConstants.NETWORK_MODE_TDSCDMA_ONLY: - raf = RAF_TD_SCDMA; - break; + return RAF_TD_SCDMA; case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA: - raf = RAF_TD_SCDMA | WCDMA; - break; + return RAF_TD_SCDMA | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA: - raf = LTE | RAF_TD_SCDMA; - break; + return LTE | RAF_TD_SCDMA; case RILConstants.NETWORK_MODE_TDSCDMA_GSM: - raf = RAF_TD_SCDMA | GSM; - break; + return RAF_TD_SCDMA | GSM; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM: - raf = LTE | RAF_TD_SCDMA | GSM; - break; + return LTE | RAF_TD_SCDMA | GSM; case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA: - raf = RAF_TD_SCDMA | GSM | WCDMA; - break; + return RAF_TD_SCDMA | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA: - raf = LTE | RAF_TD_SCDMA | WCDMA; - break; + return LTE | RAF_TD_SCDMA | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: - raf = LTE | RAF_TD_SCDMA | GSM | WCDMA; - break; + return LTE | RAF_TD_SCDMA | GSM | WCDMA; case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - raf = RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; - break; + return RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - raf = LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; - break; + return LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; + case (RILConstants.NETWORK_MODE_NR_ONLY): + return NR; + case (RILConstants.NETWORK_MODE_NR_LTE): + return NR | LTE; + case (RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO): + return NR | LTE | CDMA | EVDO; + case (RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA): + return NR | LTE | GSM | WCDMA; + case (RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA): + return NR | LTE | CDMA | EVDO | GSM | WCDMA; + case (RILConstants.NETWORK_MODE_NR_LTE_WCDMA): + return NR | LTE | WCDMA; + case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA): + return NR | LTE | RAF_TD_SCDMA; + case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM): + return NR | LTE | RAF_TD_SCDMA | GSM; + case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA): + return NR | LTE | RAF_TD_SCDMA | WCDMA; + case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA): + return NR | LTE | RAF_TD_SCDMA | GSM | WCDMA; + case (RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA): + return NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA; default: - raf = RAF_UNKNOWN; - break; + return RAF_UNKNOWN; } - - return raf; } /** @@ -249,6 +250,7 @@ public class RadioAccessFamily implements Parcelable { raf = ((CDMA & raf) > 0) ? (CDMA | raf) : raf; raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf; raf = ((LTE & raf) > 0) ? (LTE | raf) : raf; + raf = ((NR & raf) > 0) ? (NR | raf) : raf; return raf; } @@ -271,85 +273,80 @@ public class RadioAccessFamily implements Parcelable { return TelephonyManager.NETWORK_CLASS_UNKNOWN; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static int getNetworkTypeFromRaf(int raf) { - int type; - raf = getAdjustedRaf(raf); switch (raf) { case (GSM | WCDMA): - type = RILConstants.NETWORK_MODE_WCDMA_PREF; - break; + return RILConstants.NETWORK_MODE_WCDMA_PREF; case GSM: - type = RILConstants.NETWORK_MODE_GSM_ONLY; - break; + return RILConstants.NETWORK_MODE_GSM_ONLY; case WCDMA: - type = RILConstants.NETWORK_MODE_WCDMA_ONLY; - break; + return RILConstants.NETWORK_MODE_WCDMA_ONLY; case (CDMA | EVDO): - type = RILConstants.NETWORK_MODE_CDMA; - break; + return RILConstants.NETWORK_MODE_CDMA; case (LTE | CDMA | EVDO): - type = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO; - break; + return RILConstants.NETWORK_MODE_LTE_CDMA_EVDO; case (LTE | GSM | WCDMA): - type = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA; - break; + return RILConstants.NETWORK_MODE_LTE_GSM_WCDMA; case (LTE | CDMA | EVDO | GSM | WCDMA): - type = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; - break; + return RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; case LTE: - type = RILConstants.NETWORK_MODE_LTE_ONLY; - break; + return RILConstants.NETWORK_MODE_LTE_ONLY; case (LTE | WCDMA): - type = RILConstants.NETWORK_MODE_LTE_WCDMA; - break; + return RILConstants.NETWORK_MODE_LTE_WCDMA; case CDMA: - type = RILConstants.NETWORK_MODE_CDMA_NO_EVDO; - break; + return RILConstants.NETWORK_MODE_CDMA_NO_EVDO; case EVDO: - type = RILConstants.NETWORK_MODE_EVDO_NO_CDMA; - break; + return RILConstants.NETWORK_MODE_EVDO_NO_CDMA; case (GSM | WCDMA | CDMA | EVDO): - type = RILConstants.NETWORK_MODE_GLOBAL; - break; + return RILConstants.NETWORK_MODE_GLOBAL; case RAF_TD_SCDMA: - type = RILConstants.NETWORK_MODE_TDSCDMA_ONLY; - break; + return RILConstants.NETWORK_MODE_TDSCDMA_ONLY; case (RAF_TD_SCDMA | WCDMA): - type = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA; - break; + return RILConstants.NETWORK_MODE_TDSCDMA_WCDMA; case (LTE | RAF_TD_SCDMA): - type = RILConstants.NETWORK_MODE_LTE_TDSCDMA; - break; + return RILConstants.NETWORK_MODE_LTE_TDSCDMA; case (RAF_TD_SCDMA | GSM): - type = RILConstants.NETWORK_MODE_TDSCDMA_GSM; - break; + return RILConstants.NETWORK_MODE_TDSCDMA_GSM; case (LTE | RAF_TD_SCDMA | GSM): - type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; - break; + return RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; case (RAF_TD_SCDMA | GSM | WCDMA): - type = RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; - break; + return RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; case (LTE | RAF_TD_SCDMA | WCDMA): - type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; - break; + return RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; case (LTE | RAF_TD_SCDMA | GSM | WCDMA): - type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; - break; + return RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; case (RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): - type = RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; - break; + return RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; case (LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): - type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; - break; + return RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; + case (NR): + return RILConstants.NETWORK_MODE_NR_ONLY; + case (NR | LTE): + return RILConstants.NETWORK_MODE_NR_LTE; + case (NR | LTE | CDMA | EVDO): + return RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO; + case (NR | LTE | GSM | WCDMA): + return RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA; + case (NR | LTE | CDMA | EVDO | GSM | WCDMA): + return RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA; + case (NR | LTE | WCDMA): + return RILConstants.NETWORK_MODE_NR_LTE_WCDMA; + case (NR | LTE | RAF_TD_SCDMA): + return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA; + case (NR | LTE | RAF_TD_SCDMA | GSM): + return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM; + case (NR | LTE | RAF_TD_SCDMA | WCDMA): + return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA; + case (NR | LTE | RAF_TD_SCDMA | GSM | WCDMA): + return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA; + case (NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA): + return RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; default: - type = RILConstants.PREFERRED_NETWORK_MODE ; - break; + return RILConstants.PREFERRED_NETWORK_MODE; } - - return type; } public static int singleRafTypeFromString(String rafString) { @@ -376,6 +373,7 @@ public class RadioAccessFamily implements Parcelable { case "EVDO": return EVDO; case "WCDMA": return WCDMA; case "LTE_CA": return RAF_LTE_CA; + case "NR": return RAF_NR; default: return RAF_UNKNOWN; } } diff --git a/telephony/java/android/telephony/Rlog.java b/telephony/java/android/telephony/Rlog.java index 5f2fa335135f..cdab2dc54dd2 100644 --- a/telephony/java/android/telephony/Rlog.java +++ b/telephony/java/android/telephony/Rlog.java @@ -65,7 +65,7 @@ public final class Rlog { return Log.println_native(Log.LOG_ID_RADIO, Log.INFO, tag, msg); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static int i(String tag, String msg, Throwable tr) { return Log.println_native(Log.LOG_ID_RADIO, Log.INFO, tag, msg + '\n' + Log.getStackTraceString(tr)); diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 78f05168198f..9fc1b6f76e77 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -317,19 +317,19 @@ public class ServiceState implements Parcelable { @RilRadioTechnology private int mRilDataRadioTechnology; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private boolean mCssIndicator; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private int mNetworkId; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private int mSystemId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaRoamingIndicator; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaDefaultRoamingIndicator; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaEriIconIndex; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mCdmaEriIconMode; @UnsupportedAppUsage @@ -1071,7 +1071,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setDataRegState(int state) { mDataRegState = state; if (VDBG) Rlog.d(LOG_TAG, "[ServiceState] setDataRegState=" + mDataRegState); @@ -1101,7 +1101,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setVoiceRoamingType(@RoamingType int type) { NetworkRegistrationState regState = getNetworkRegistrationState( NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN); @@ -1122,7 +1122,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setDataRoamingType(@RoamingType int type) { NetworkRegistrationState regState = getNetworkRegistrationState( NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN); @@ -1139,7 +1139,7 @@ public class ServiceState implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setEmergencyOnly(boolean emergencyOnly) { mIsEmergencyOnly = emergencyOnly; } @@ -1147,7 +1147,7 @@ public class ServiceState implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaRoamingIndicator(int roaming) { this.mCdmaRoamingIndicator = roaming; } @@ -1155,7 +1155,7 @@ public class ServiceState implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaDefaultRoamingIndicator (int roaming) { this.mCdmaDefaultRoamingIndicator = roaming; } @@ -1163,7 +1163,7 @@ public class ServiceState implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaEriIconIndex(int index) { this.mCdmaEriIconIndex = index; } @@ -1171,7 +1171,7 @@ public class ServiceState implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCdmaEriIconMode(int mode) { this.mCdmaEriIconMode = mode; } @@ -1232,7 +1232,7 @@ public class ServiceState implements Parcelable { * @param b second obj * @return true if two objects equal or both are null */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static boolean equalsHandlesNulls (Object a, Object b) { return (a == null) ? (b == null) : a.equals (b); } @@ -1389,7 +1389,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCssIndicator(int css) { this.mCssIndicator = (css != 0); } @@ -1569,7 +1569,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getCssIndicator() { return this.mCssIndicator ? 1 : 0; } @@ -1629,7 +1629,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static boolean bearerBitmapHasCdma(int radioTechnologyBitmap) { return (RIL_RADIO_CDMA_TECHNOLOGY_BITMASK & radioTechnologyBitmap) != 0; } diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index 240b8a981e70..ef185c5eeaf1 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -16,16 +16,14 @@ package android.telephony; +import android.annotation.NonNull; import android.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.CarrierConfigManager; -import android.util.Log; +import android.os.PersistableBundle; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Objects; /** @@ -59,6 +57,8 @@ public class SignalStrength implements Parcelable { /** @hide */ @UnsupportedAppUsage public static final int NUM_SIGNAL_STRENGTH_BINS = 5; + + /** SIGNAL_STRENGTH_NAMES is currently used by BatteryStats, but to-be-removed soon. */ /** @hide */ public static final String[] SIGNAL_STRENGTH_NAMES = { "none", "poor", "moderate", "good", "great" @@ -72,66 +72,22 @@ public class SignalStrength implements Parcelable { public static final int INVALID = Integer.MAX_VALUE; private static final int LTE_RSRP_THRESHOLDS_NUM = 4; - private static final int MAX_LTE_RSRP = -44; - private static final int MIN_LTE_RSRP = -140; private static final int WCDMA_RSCP_THRESHOLDS_NUM = 4; - private static final int MAX_WCDMA_RSCP = -24; - private static final int MIN_WCDMA_RSCP = -120; /* The type of signal measurement */ - private static final String MEASUMENT_TYPE_RSCP = "rscp"; + private static final String MEASUREMENT_TYPE_RSCP = "rscp"; - /** Parameters reported by the Radio */ - @UnsupportedAppUsage - private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 - @UnsupportedAppUsage - private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 - @UnsupportedAppUsage - private int mCdmaDbm; // This value is the RSSI value - @UnsupportedAppUsage - private int mCdmaEcio; // This value is the Ec/Io - @UnsupportedAppUsage - private int mEvdoDbm; // This value is the EVDO RSSI value - @UnsupportedAppUsage - private int mEvdoEcio; // This value is the EVDO Ec/Io - @UnsupportedAppUsage - private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio - @UnsupportedAppUsage - private int mLteSignalStrength; - @UnsupportedAppUsage - private int mLteRsrp; - @UnsupportedAppUsage - private int mLteRsrq; - @UnsupportedAppUsage - private int mLteRssnr; - @UnsupportedAppUsage - private int mLteCqi; - @UnsupportedAppUsage - private int mTdScdmaRscp; // Valid values are -24...-120dBm or INVALID if unknown - private int mWcdmaSignalStrength; - private int mWcdmaRscpAsu; // the WCDMA RSCP in ASU as reported from the HAL - @UnsupportedAppUsage - private int mWcdmaRscp; // the WCDMA RSCP in dBm + CellSignalStrengthCdma mCdma; + CellSignalStrengthGsm mGsm; + CellSignalStrengthWcdma mWcdma; + CellSignalStrengthTdscdma mTdscdma; + CellSignalStrengthLte mLte; /** Parameters from the framework */ @UnsupportedAppUsage private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating // signal strength level - private boolean mIsGsm; // This value is set by the ServiceStateTracker - // onSignalStrengthResult. - private boolean mUseOnlyRsrpForLteLevel; // Use only RSRP for the number of LTE signal bar. - - // The threshold of LTE RSRP for determining the display level of LTE signal bar. Note that the - // min and max are fixed at MIN_LTE_RSRP (-140) and MAX_LTE_RSRP (-44). - private int mLteRsrpThresholds[] = new int[LTE_RSRP_THRESHOLDS_NUM]; - - // The type of default measurement for determining the display level of WCDMA signal bar. - private String mWcdmaDefaultSignalMeasurement; - - // The threshold of WCDMA RSCP for determining the display level of WCDMA signal bar. Note that - // the min and max are fixed at MIN_WCDMA_RSCP (-120) and MAX_WCDMA_RSCP (-24). - private int mWcdmaRscpThresholds[] = new int[WCDMA_RSCP_THRESHOLDS_NUM]; /** * Create a new SignalStrength from a intent notifier Bundle @@ -153,47 +109,17 @@ public class SignalStrength implements Parcelable { } /** - * Empty constructor - * - * @hide - */ - @UnsupportedAppUsage - public SignalStrength() { - this(true); - } - - /** * This constructor is used to create SignalStrength with default - * values and set the gsmFlag with the value passed in the input + * values. * - * @param gsmFlag true if Gsm Phone,false if Cdma phone * @return newly created SignalStrength * @hide */ @UnsupportedAppUsage - public SignalStrength(boolean gsmFlag) { - mGsmSignalStrength = 99; - mGsmBitErrorRate = -1; - mCdmaDbm = INVALID; - mCdmaEcio = -1; - mEvdoDbm = INVALID; - mEvdoEcio = -1; - mEvdoSnr = -1; - mLteSignalStrength = 99; - mLteRsrp = INVALID; - mLteRsrq = INVALID; - mLteRssnr = INVALID; - mLteCqi = INVALID; - mTdScdmaRscp = INVALID; - mWcdmaSignalStrength = 99; - mWcdmaRscp = INVALID; - mWcdmaRscpAsu = 255; - mLteRsrpBoost = 0; - mIsGsm = gsmFlag; - mUseOnlyRsrpForLteLevel = false; - mWcdmaDefaultSignalMeasurement = ""; - setLteRsrpThresholds(getDefaultLteRsrpThresholds()); - setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds()); + public SignalStrength() { + this(new CellSignalStrengthCdma(), new CellSignalStrengthGsm(), + new CellSignalStrengthWcdma(), new CellSignalStrengthTdscdma(), + new CellSignalStrengthLte()); } /** @@ -202,68 +128,64 @@ public class SignalStrength implements Parcelable { * @hide */ public SignalStrength( - int gsmSignalStrength, int gsmBitErrorRate, - int cdmaDbm, int cdmaEcio, - int evdoDbm, int evdoEcio, int evdoSnr, - int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, - int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscpAsu, - // values Added by config - int lteRsrpBoost, boolean gsmFlag, boolean lteLevelBaseOnRsrp, - String wcdmaDefaultMeasurement) { - mGsmSignalStrength = gsmSignalStrength; - mGsmBitErrorRate = gsmBitErrorRate; - mCdmaDbm = cdmaDbm; - mCdmaEcio = cdmaEcio; - mEvdoDbm = evdoDbm; - mEvdoEcio = evdoEcio; - mEvdoSnr = evdoSnr; - mLteSignalStrength = lteSignalStrength; - mLteRsrp = lteRsrp; - mLteRsrq = lteRsrq; - mLteRssnr = lteRssnr; - mLteCqi = lteCqi; - mTdScdmaRscp = INVALID; - mWcdmaSignalStrength = wcdmaSignalStrength; - mWcdmaRscpAsu = wcdmaRscpAsu; - mWcdmaRscp = wcdmaRscpAsu - 120; - mLteRsrpBoost = lteRsrpBoost; - mIsGsm = gsmFlag; - mUseOnlyRsrpForLteLevel = lteLevelBaseOnRsrp; - mWcdmaDefaultSignalMeasurement = wcdmaDefaultMeasurement; - setLteRsrpThresholds(getDefaultLteRsrpThresholds()); - setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds()); - if (DBG) log("initialize: " + toString()); + @NonNull CellSignalStrengthCdma cdma, + @NonNull CellSignalStrengthGsm gsm, + @NonNull CellSignalStrengthWcdma wcdma, + @NonNull CellSignalStrengthTdscdma tdscdma, + @NonNull CellSignalStrengthLte lte) { + mCdma = cdma; + mGsm = gsm; + mWcdma = wcdma; + mTdscdma = tdscdma; + mLte = lte; + mLteRsrpBoost = 0; } /** - * Constructor for only values provided by Radio HAL V1.0 + * Constructor for Radio HAL V1.0 * * @hide */ - public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, - int cdmaDbm, int cdmaEcio, - int evdoDbm, int evdoEcio, int evdoSnr, - int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, - int tdScdmaRscp) { - this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, - evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, - lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, 99, INVALID, 0, true, false, ""); + public SignalStrength(android.hardware.radio.V1_0.SignalStrength signalStrength) { + this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo), + new CellSignalStrengthGsm(signalStrength.gw), + new CellSignalStrengthWcdma(), + new CellSignalStrengthTdscdma(signalStrength.tdScdma), + new CellSignalStrengthLte(signalStrength.lte)); } /** - * Constructor for only values provided by Radio HAL V1.2 + * Constructor for Radio HAL V1.2 * * @hide */ - public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, - int cdmaDbm, int cdmaEcio, - int evdoDbm, int evdoEcio, int evdoSnr, - int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, - int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscp) { - this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, - evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, - lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, wcdmaSignalStrength, wcdmaRscp, 0, true, - false, ""); + public SignalStrength(android.hardware.radio.V1_2.SignalStrength signalStrength) { + this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo), + new CellSignalStrengthGsm(signalStrength.gsm), + new CellSignalStrengthWcdma(signalStrength.wcdma), + new CellSignalStrengthTdscdma(signalStrength.tdScdma), + new CellSignalStrengthLte(signalStrength.lte)); + } + + private CellSignalStrength getPrimary() { + // This behavior is intended to replicate the legacy behavior of getLevel() by prioritizing + // newer faster RATs for default/for display purposes. + if (mLte.isValid()) return mLte; + if (mCdma.isValid()) return mCdma; + if (mTdscdma.isValid()) return mTdscdma; + if (mWcdma.isValid()) return mWcdma; + if (mGsm.isValid()) return mGsm; + return mLte; + } + + /** @hide */ + public void updateLevel(PersistableBundle cc, ServiceState ss) { + mLteRsrpBoost = ss.getLteEarfcnRsrpBoost(); + mCdma.updateLevel(cc, ss); + mGsm.updateLevel(cc, ss); + mWcdma.updateLevel(cc, ss); + mTdscdma.updateLevel(cc, ss); + mLte.updateLevel(cc, ss); } /** @@ -283,28 +205,12 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage protected void copyFrom(SignalStrength s) { - mGsmSignalStrength = s.mGsmSignalStrength; - mGsmBitErrorRate = s.mGsmBitErrorRate; - mCdmaDbm = s.mCdmaDbm; - mCdmaEcio = s.mCdmaEcio; - mEvdoDbm = s.mEvdoDbm; - mEvdoEcio = s.mEvdoEcio; - mEvdoSnr = s.mEvdoSnr; - mLteSignalStrength = s.mLteSignalStrength; - mLteRsrp = s.mLteRsrp; - mLteRsrq = s.mLteRsrq; - mLteRssnr = s.mLteRssnr; - mLteCqi = s.mLteCqi; - mTdScdmaRscp = s.mTdScdmaRscp; - mWcdmaSignalStrength = s.mWcdmaSignalStrength; - mWcdmaRscpAsu = s.mWcdmaRscpAsu; - mWcdmaRscp = s.mWcdmaRscp; + mCdma = new CellSignalStrengthCdma(s.mCdma); + mGsm = new CellSignalStrengthGsm(s.mGsm); + mWcdma = new CellSignalStrengthWcdma(s.mWcdma); + mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma); + mLte = new CellSignalStrengthLte(s.mLte); mLteRsrpBoost = s.mLteRsrpBoost; - mIsGsm = s.mIsGsm; - mUseOnlyRsrpForLteLevel = s.mUseOnlyRsrpForLteLevel; - mWcdmaDefaultSignalMeasurement = s.mWcdmaDefaultSignalMeasurement; - setLteRsrpThresholds(s.mLteRsrpThresholds); - setWcdmaRscpThresholds(s.mWcdmaRscpThresholds); } /** @@ -316,56 +222,25 @@ public class SignalStrength implements Parcelable { public SignalStrength(Parcel in) { if (DBG) log("Size of signalstrength parcel:" + in.dataSize()); - mGsmSignalStrength = in.readInt(); - mGsmBitErrorRate = in.readInt(); - mCdmaDbm = in.readInt(); - mCdmaEcio = in.readInt(); - mEvdoDbm = in.readInt(); - mEvdoEcio = in.readInt(); - mEvdoSnr = in.readInt(); - mLteSignalStrength = in.readInt(); - mLteRsrp = in.readInt(); - mLteRsrq = in.readInt(); - mLteRssnr = in.readInt(); - mLteCqi = in.readInt(); - mTdScdmaRscp = in.readInt(); - mWcdmaSignalStrength = in.readInt(); - mWcdmaRscpAsu = in.readInt(); - mWcdmaRscp = in.readInt(); + mCdma = in.readParcelable(CellSignalStrengthCdma.class.getClassLoader()); + mGsm = in.readParcelable(CellSignalStrengthGsm.class.getClassLoader()); + mWcdma = in.readParcelable(CellSignalStrengthWcdma.class.getClassLoader()); + mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader()); + mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader()); mLteRsrpBoost = in.readInt(); - mIsGsm = in.readBoolean(); - mUseOnlyRsrpForLteLevel = in.readBoolean(); - mWcdmaDefaultSignalMeasurement = in.readString(); - in.readIntArray(mLteRsrpThresholds); - in.readIntArray(mWcdmaRscpThresholds); } /** * {@link Parcelable#writeToParcel} */ public void writeToParcel(Parcel out, int flags) { - out.writeInt(mGsmSignalStrength); - out.writeInt(mGsmBitErrorRate); - out.writeInt(mCdmaDbm); - out.writeInt(mCdmaEcio); - out.writeInt(mEvdoDbm); - out.writeInt(mEvdoEcio); - out.writeInt(mEvdoSnr); - out.writeInt(mLteSignalStrength); - out.writeInt(mLteRsrp); - out.writeInt(mLteRsrq); - out.writeInt(mLteRssnr); - out.writeInt(mLteCqi); - out.writeInt(mTdScdmaRscp); - out.writeInt(mWcdmaSignalStrength); - out.writeInt(mWcdmaRscpAsu); - out.writeInt(mWcdmaRscp); + out.writeParcelable(mCdma, flags); + out.writeParcelable(mGsm, flags); + out.writeParcelable(mWcdma, flags); + out.writeParcelable(mTdscdma, flags); + out.writeParcelable(mLte, flags); + out.writeInt(mLteRsrpBoost); - out.writeBoolean(mIsGsm); - out.writeBoolean(mUseOnlyRsrpForLteLevel); - out.writeString(mWcdmaDefaultSignalMeasurement); - out.writeIntArray(mLteRsrpThresholds); - out.writeIntArray(mWcdmaRscpThresholds); } /** @@ -392,153 +267,21 @@ public class SignalStrength implements Parcelable { }; /** - * Validate the individual signal strength fields as per the range - * specified in ril.h - * Set to invalid any field that is not in the valid range - * Cdma, evdo, lte rsrp & rsrq values are sign converted - * when received from ril interface - * - * @return - * Valid values for all signalstrength fields - * @hide - */ - @UnsupportedAppUsage - public void validateInput() { - if (DBG) log("Signal before validate=" + this); - // TS 27.007 8.5 - mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99; - mWcdmaSignalStrength = (mWcdmaSignalStrength >= 0) ? mWcdmaSignalStrength : 99; - mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99; - // BER no change; - - // WCDMA RSCP valid values are -120 through -24 as defined in TS 27.007 8.69 - // but are reported in ASU which is 0 through 96, so we do the conversion here - mWcdmaRscpAsu = - ((mWcdmaRscpAsu - 120 >= MIN_WCDMA_RSCP) && (mWcdmaRscpAsu - 120 <= MAX_WCDMA_RSCP)) - ? mWcdmaRscpAsu : 255; - mWcdmaRscp = ((mWcdmaRscp >= MIN_WCDMA_RSCP) && (mWcdmaRscp <= MAX_WCDMA_RSCP)) - ? mWcdmaRscp : INVALID; - - mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120; - mCdmaEcio = (mCdmaEcio >= 0) ? -mCdmaEcio : -160; - - mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120; - mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -160; - mEvdoSnr = ((mEvdoSnr >= 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1; - - // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC - mLteRsrp = ((-mLteRsrp >= MIN_LTE_RSRP) && (-mLteRsrp <= MAX_LTE_RSRP)) ? -mLteRsrp - : SignalStrength.INVALID; - mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID; - mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr - : SignalStrength.INVALID; - - mTdScdmaRscp = ((mTdScdmaRscp >= 0) && (mTdScdmaRscp <= 96)) - ? (mTdScdmaRscp - 120) : SignalStrength.INVALID; - // Cqi no change - if (DBG) log("Signal after validate=" + this); - } - - /** - * Fix {@link #mIsGsm} based on the signal strength data. + * Get the GSM RSSI in ASU. * - * @hide - */ - public void fixType() { - mIsGsm = getCdmaRelatedSignalStrength() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - } - - /** - * @param true - Gsm, Lte phones - * false - Cdma phones - * - * Used by voice phone to set the mIsGsm - * flag - * @hide - */ - public void setGsm(boolean gsmFlag) { - mIsGsm = gsmFlag; - } - - /** - * @param useOnlyRsrpForLteLevel true if it uses only RSRP for the number of LTE signal bar, - * otherwise false. - * - * Used by phone to use only RSRP or not for the number of LTE signal bar. - * @hide - */ - public void setUseOnlyRsrpForLteLevel(boolean useOnlyRsrpForLteLevel) { - mUseOnlyRsrpForLteLevel = useOnlyRsrpForLteLevel; - } - - /** - * @param defaultMeasurement sets the type of WCDMA default signal measurement - * - * Used by phone to determine default measurement type for calculation WCDMA signal level. - * @hide - */ - public void setWcdmaDefaultSignalMeasurement(String defaultMeasurement) { - mWcdmaDefaultSignalMeasurement = defaultMeasurement; - } - - /** - * @param lteRsrpBoost - signal strength offset - * - * Used by phone to set the lte signal strength offset which will be - * reduced from rsrp threshold while calculating signal strength level - * - * @hide - */ - public void setLteRsrpBoost(int lteRsrpBoost) { - mLteRsrpBoost = lteRsrpBoost; - } - - /** - * Sets the threshold array for determining the display level of LTE signal bar. - * - * @param lteRsrpThresholds int array for determining the display level. + * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 * - * @hide - */ - public void setLteRsrpThresholds(int[] lteRsrpThresholds) { - if ((lteRsrpThresholds == null) - || (lteRsrpThresholds.length != LTE_RSRP_THRESHOLDS_NUM)) { - Log.wtf(LOG_TAG, "setLteRsrpThresholds - lteRsrpThresholds is invalid."); - return; - } - System.arraycopy(lteRsrpThresholds, 0, mLteRsrpThresholds, 0, LTE_RSRP_THRESHOLDS_NUM); - } - - /** - * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS - * 27.007 8.5 + * @return RSSI in ASU 0..31, 99, or UNAVAILABLE */ public int getGsmSignalStrength() { - return this.mGsmSignalStrength; + return mGsm.getAsuLevel(); } /** * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ public int getGsmBitErrorRate() { - return this.mGsmBitErrorRate; - } - - /** - * Sets the threshold array for determining the display level of WCDMA signal bar. - * - * @param wcdmaRscpThresholds int array for determining the display level. - * - * @hide - */ - public void setWcdmaRscpThresholds(int[] wcdmaRscpThresholds) { - if ((wcdmaRscpThresholds == null) - || (wcdmaRscpThresholds.length != WCDMA_RSCP_THRESHOLDS_NUM)) { - Log.wtf(LOG_TAG, "setWcdmaRscpThresholds - wcdmaRscpThresholds is invalid."); - return; - } - System.arraycopy(wcdmaRscpThresholds, 0, mWcdmaRscpThresholds, 0, - WCDMA_RSCP_THRESHOLDS_NUM); + return mGsm.getBitErrorRate(); } /** @@ -547,14 +290,14 @@ public class SignalStrength implements Parcelable { * @return the CDMA RSSI value or {@link #INVALID} if invalid */ public int getCdmaDbm() { - return this.mCdmaDbm; + return mCdma.getCdmaDbm(); } /** * Get the CDMA Ec/Io value in dB*10 */ public int getCdmaEcio() { - return this.mCdmaEcio; + return mCdma.getCdmaEcio(); } /** @@ -563,51 +306,51 @@ public class SignalStrength implements Parcelable { * @return the EVDO RSSI value or {@link #INVALID} if invalid */ public int getEvdoDbm() { - return this.mEvdoDbm; + return mCdma.getEvdoDbm(); } /** * Get the EVDO Ec/Io value in dB*10 */ public int getEvdoEcio() { - return this.mEvdoEcio; + return mCdma.getEvdoEcio(); } /** * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest. */ public int getEvdoSnr() { - return this.mEvdoSnr; + return mCdma.getEvdoSnr(); } /** @hide */ @UnsupportedAppUsage public int getLteSignalStrength() { - return mLteSignalStrength; + return mLte.getRssi(); } /** @hide */ @UnsupportedAppUsage public int getLteRsrp() { - return mLteRsrp; + return mLte.getRsrp(); } /** @hide */ @UnsupportedAppUsage public int getLteRsrq() { - return mLteRsrq; + return mLte.getRsrq(); } /** @hide */ @UnsupportedAppUsage public int getLteRssnr() { - return mLteRssnr; + return mLte.getRssnr(); } /** @hide */ @UnsupportedAppUsage public int getLteCqi() { - return mLteCqi; + return mLte.getCqi(); } /** @hide */ @@ -624,9 +367,12 @@ public class SignalStrength implements Parcelable { * while 4 represents a very strong signal strength. */ public int getLevel() { - int level = mIsGsm ? getGsmRelatedSignalStrength() : getCdmaRelatedSignalStrength(); - if (DBG) log("getLevel=" + level); - return level; + int level = getPrimary().getLevel(); + if (level < SIGNAL_STRENGTH_NONE_OR_UNKNOWN || level > SIGNAL_STRENGTH_GREAT) { + log("Invalid Level " + level + ", this=" + this); + return SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + } + return getPrimary().getLevel(); } /** @@ -636,33 +382,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getAsuLevel() { - int asuLevel = 0; - if (mIsGsm) { - if (mLteRsrp != SignalStrength.INVALID) { - asuLevel = getLteAsuLevel(); - } else if (mTdScdmaRscp != SignalStrength.INVALID) { - asuLevel = getTdScdmaAsuLevel(); - } else if (mWcdmaRscp != SignalStrength.INVALID) { - asuLevel = getWcdmaAsuLevel(); - } else { - asuLevel = getGsmAsuLevel(); - } - } else { - int cdmaAsuLevel = getCdmaAsuLevel(); - int evdoAsuLevel = getEvdoAsuLevel(); - if (evdoAsuLevel == 0) { - /* We don't know evdo use, cdma */ - asuLevel = cdmaAsuLevel; - } else if (cdmaAsuLevel == 0) { - /* We don't know cdma use, evdo */ - asuLevel = evdoAsuLevel; - } else { - /* We know both, use the lowest level */ - asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel; - } - } - if (DBG) log("getAsuLevel=" + asuLevel); - return asuLevel; + return getPrimary().getAsuLevel(); } /** @@ -672,30 +392,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getDbm() { - int dBm = INVALID; - - if(isGsm()) { - dBm = getLteDbm(); - if (dBm == INVALID) { - if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { - if (getWcdmaDbm() == INVALID) { - dBm = getGsmDbm(); - } else { - dBm = getWcdmaDbm(); - } - } else { - dBm = getTdScdmaDbm(); - } - } - } else { - int cdmaDbm = getCdmaDbm(); - int evdoDbm = getEvdoDbm(); - - return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm - : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm)); - } - if (DBG) log("getDbm=" + dBm); - return dBm; + return getPrimary().getDbm(); } /** @@ -705,17 +402,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getGsmDbm() { - int dBm; - - int gsmSignalStrength = getGsmSignalStrength(); - int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); - if (asu != -1) { - dBm = -113 + (2 * asu); - } else { - dBm = -1; - } - if (DBG) log("getGsmDbm=" + dBm); - return dBm; + return mGsm.getDbm(); } /** @@ -725,20 +412,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getGsmLevel() { - int level; - - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int asu = getGsmSignalStrength(); - if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT; - else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD; - else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE; - else level = SIGNAL_STRENGTH_POOR; - if (DBG) log("getGsmLevel=" + level); - return level; + return mGsm.getLevel(); } /** @@ -748,13 +422,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getGsmAsuLevel() { - // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 - // asu = 0 (-113dB or less) is very weak - // signal, its better to show 0 bars to the user in such cases. - // asu = 99 is a special case, where the signal strength is unknown. - int level = getGsmSignalStrength(); - if (DBG) log("getGsmAsuLevel=" + level); - return level; + return mGsm.getAsuLevel(); } /** @@ -764,27 +432,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getCdmaLevel() { - final int cdmaDbm = getCdmaDbm(); - final int cdmaEcio = getCdmaEcio(); - int levelDbm; - int levelEcio; - - if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; - else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; - else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; - else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; - else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - - // Ec/Io are in dB*10 - if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; - else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; - else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; - else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; - else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - - int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; - if (DBG) log("getCdmaLevel=" + level); - return level; + return mCdma.getLevel(); } /** @@ -794,29 +442,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getCdmaAsuLevel() { - final int cdmaDbm = getCdmaDbm(); - final int cdmaEcio = getCdmaEcio(); - int cdmaAsuLevel; - int ecioAsuLevel; - - if (cdmaDbm >= -75) cdmaAsuLevel = 16; - else if (cdmaDbm >= -82) cdmaAsuLevel = 8; - else if (cdmaDbm >= -90) cdmaAsuLevel = 4; - else if (cdmaDbm >= -95) cdmaAsuLevel = 2; - else if (cdmaDbm >= -100) cdmaAsuLevel = 1; - else cdmaAsuLevel = 99; - - // Ec/Io are in dB*10 - if (cdmaEcio >= -90) ecioAsuLevel = 16; - else if (cdmaEcio >= -100) ecioAsuLevel = 8; - else if (cdmaEcio >= -115) ecioAsuLevel = 4; - else if (cdmaEcio >= -130) ecioAsuLevel = 2; - else if (cdmaEcio >= -150) ecioAsuLevel = 1; - else ecioAsuLevel = 99; - - int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; - if (DBG) log("getCdmaAsuLevel=" + level); - return level; + return mCdma.getAsuLevel(); } /** @@ -826,26 +452,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getEvdoLevel() { - int evdoDbm = getEvdoDbm(); - int evdoSnr = getEvdoSnr(); - int levelEvdoDbm; - int levelEvdoSnr; - - if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; - else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; - else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; - else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; - else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - - if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; - else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; - else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; - else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; - else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - - int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; - if (DBG) log("getEvdoLevel=" + level); - return level; + return mCdma.getEvdoLevel(); } /** @@ -855,28 +462,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getEvdoAsuLevel() { - int evdoDbm = getEvdoDbm(); - int evdoSnr = getEvdoSnr(); - int levelEvdoDbm; - int levelEvdoSnr; - - if (evdoDbm >= -65) levelEvdoDbm = 16; - else if (evdoDbm >= -75) levelEvdoDbm = 8; - else if (evdoDbm >= -85) levelEvdoDbm = 4; - else if (evdoDbm >= -95) levelEvdoDbm = 2; - else if (evdoDbm >= -105) levelEvdoDbm = 1; - else levelEvdoDbm = 99; - - if (evdoSnr >= 7) levelEvdoSnr = 16; - else if (evdoSnr >= 6) levelEvdoSnr = 8; - else if (evdoSnr >= 5) levelEvdoSnr = 4; - else if (evdoSnr >= 3) levelEvdoSnr = 2; - else if (evdoSnr >= 1) levelEvdoSnr = 1; - else levelEvdoSnr = 99; - - int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; - if (DBG) log("getEvdoAsuLevel=" + level); - return level; + return mCdma.getEvdoAsuLevel(); } /** @@ -886,7 +472,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getLteDbm() { - return mLteRsrp; + return mLte.getRsrp(); } /** @@ -896,83 +482,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getLteLevel() { - /* - * TS 36.214 Physical Layer Section 5.1.3 - * TS 36.331 RRC - * - * RSSI = received signal + noise - * RSRP = reference signal dBm - * RSRQ = quality of signal dB = Number of Resource blocks*RSRP/RSSI - * SNR = gain = signal/noise ratio = -10log P1/P2 dB - */ - int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1; - - if (mLteRsrp > MAX_LTE_RSRP || mLteRsrp < MIN_LTE_RSRP) { - if (mLteRsrp != INVALID) { - Log.wtf(LOG_TAG, "getLteLevel - invalid lte rsrp: mLteRsrp=" + mLteRsrp); - } - } else if (mLteRsrp >= (mLteRsrpThresholds[3] - mLteRsrpBoost)) { - rsrpIconLevel = SIGNAL_STRENGTH_GREAT; - } else if (mLteRsrp >= (mLteRsrpThresholds[2] - mLteRsrpBoost)) { - rsrpIconLevel = SIGNAL_STRENGTH_GOOD; - } else if (mLteRsrp >= (mLteRsrpThresholds[1] - mLteRsrpBoost)) { - rsrpIconLevel = SIGNAL_STRENGTH_MODERATE; - } else if (mLteRsrp >= (mLteRsrpThresholds[0] - mLteRsrpBoost)) { - rsrpIconLevel = SIGNAL_STRENGTH_POOR; - } else { - rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - } - - if (useOnlyRsrpForLteLevel()) { - log("getLTELevel - rsrp = " + rsrpIconLevel); - if (rsrpIconLevel != -1) { - return rsrpIconLevel; - } - } - - /* - * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 - * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars - * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna - * Icon Only - */ - if (mLteRssnr > 300) snrIconLevel = -1; - else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; - else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; - else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; - else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; - else if (mLteRssnr >= -200) - snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - - if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:" - + rsrpIconLevel + " snrIconLevel:" + snrIconLevel - + " lteRsrpBoost:" + mLteRsrpBoost); - - /* Choose a measurement type to use for notification */ - if (snrIconLevel != -1 && rsrpIconLevel != -1) { - /* - * The number of bars displayed shall be the smaller of the bars - * associated with LTE RSRP and the bars associated with the LTE - * RS_SNR - */ - return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); - } - - if (snrIconLevel != -1) return snrIconLevel; - - if (rsrpIconLevel != -1) return rsrpIconLevel; - - /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ - if (mLteSignalStrength > 31) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT; - else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD; - else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; - else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR; - - if (DBG) log("getLteLevel - rssi:" + mLteSignalStrength + " rssiIconLevel:" - + rssiIconLevel); - return rssiIconLevel; - + return mLte.getLevel(); } /** @@ -983,41 +493,14 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getLteAsuLevel() { - int lteAsuLevel = 99; - int lteDbm = getLteDbm(); - /* - * 3GPP 27.007 (Ver 10.3.0) Sec 8.69 - * 0 -140 dBm or less - * 1 -139 dBm - * 2...96 -138... -44 dBm - * 97 -43 dBm or greater - * 255 not known or not detectable - */ - /* - * validateInput will always give a valid range between -140 t0 -44 as - * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255 - * and not 97 or 0 - */ - if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255; - else lteAsuLevel = lteDbm + 140; - if (DBG) log("Lte Asu level: "+lteAsuLevel); - return lteAsuLevel; + return mLte.getAsuLevel(); } /** * @return true if this is for GSM */ public boolean isGsm() { - return this.mIsGsm; - } - - /** - * @return true if it uses only RSRP for the number of LTE signal bar, otherwise false. - * - * @hide - */ - public boolean useOnlyRsrpForLteLevel() { - return this.mUseOnlyRsrpForLteLevel; + return !(getPrimary() instanceof CellSignalStrengthCdma); } /** @@ -1027,7 +510,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getTdScdmaDbm() { - return this.mTdScdmaRscp; + return mTdscdma.getRscp(); } /** @@ -1040,19 +523,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getTdScdmaLevel() { - final int tdScdmaDbm = getTdScdmaDbm(); - int level; - - if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID)) - level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT; - else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD; - else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE; - else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR; - else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - - if (DBG) log("getTdScdmaLevel = " + level); - return level; + return mTdscdma.getLevel(); } /** @@ -1062,13 +533,7 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getTdScdmaAsuLevel() { - final int tdScdmaDbm = getTdScdmaDbm(); - int tdScdmaAsuLevel; - - if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255; - else tdScdmaAsuLevel = tdScdmaDbm + 120; - if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel); - return tdScdmaAsuLevel; + return mTdscdma.getAsuLevel(); } /** @@ -1077,7 +542,7 @@ public class SignalStrength implements Parcelable { * @hide */ public int getWcdmaRscp() { - return mWcdmaRscp; + return mWcdma.getRscp(); } /** @@ -1094,14 +559,7 @@ public class SignalStrength implements Parcelable { * 96 -24 dBm or greater * 255 not known or not detectable */ - final int wcdmaDbm = getWcdmaDbm(); - int wcdmaAsuLevel = 255; - // validateInput will always give a valid range between -120 to -24 as per ril.h. so RSCP - // outside range is already set to INVALID - if (wcdmaDbm == SignalStrength.INVALID) wcdmaAsuLevel = 255; - else wcdmaAsuLevel = wcdmaDbm + 120; - if (DBG) log("Wcdma Asu level: " + wcdmaAsuLevel); - return wcdmaAsuLevel; + return mWcdma.getAsuLevel(); } /** @@ -1110,7 +568,7 @@ public class SignalStrength implements Parcelable { * @hide */ public int getWcdmaDbm() { - return mWcdmaRscp; + return mWcdma.getDbm(); } /** @@ -1119,55 +577,7 @@ public class SignalStrength implements Parcelable { * @hide */ public int getWcdmaLevel() { - int level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - - if (mWcdmaDefaultSignalMeasurement == null) { - Log.wtf(LOG_TAG, "getWcdmaLevel - WCDMA default signal measurement is invalid."); - return level; - } - - switch (mWcdmaDefaultSignalMeasurement) { - case MEASUMENT_TYPE_RSCP: - // RSCP valid values are (-120 through -24) as defined in TS 27.007 8.69 - if (mWcdmaRscp < MIN_WCDMA_RSCP || mWcdmaRscp > MAX_WCDMA_RSCP) { - if (mWcdmaRscp != INVALID) { - Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSCP: mWcdmaRscp=" - + mWcdmaRscp); - } - } else if (mWcdmaRscp >= mWcdmaRscpThresholds[3]) { - level = SIGNAL_STRENGTH_GREAT; - } else if (mWcdmaRscp >= mWcdmaRscpThresholds[2]) { - level = SIGNAL_STRENGTH_GOOD; - } else if (mWcdmaRscp >= mWcdmaRscpThresholds[1]) { - level = SIGNAL_STRENGTH_MODERATE; - } else if (mWcdmaRscp >= mWcdmaRscpThresholds[0]) { - level = SIGNAL_STRENGTH_POOR; - } - if (DBG) log("getWcdmaLevel=" + level + " WcdmaRscp=" + mWcdmaRscp); - break; - - default: - // RSSI valid values are (0..31) as defined in TS 27.007 8.5 - if (mWcdmaSignalStrength < 0 || mWcdmaSignalStrength > 31) { - if (mWcdmaSignalStrength != 99) { - Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSSI: mWcdmaSignalStrength=" - + mWcdmaSignalStrength); - } - } else if (mWcdmaSignalStrength >= 18) { - level = SIGNAL_STRENGTH_GREAT; - } else if (mWcdmaSignalStrength >= 13) { - level = SIGNAL_STRENGTH_GOOD; - } else if (mWcdmaSignalStrength >= 8) { - level = SIGNAL_STRENGTH_MODERATE; - } else if (mWcdmaSignalStrength >= 3) { - level = SIGNAL_STRENGTH_POOR; - } - if (DBG) log("getWcdmaLevel=" + level + " WcdmaSignalStrength=" + - mWcdmaSignalStrength); - break; - - } - return level; + return mWcdma.getLevel(); } /** @@ -1175,18 +585,7 @@ public class SignalStrength implements Parcelable { */ @Override public int hashCode() { - int primeNum = 31; - return ((mGsmSignalStrength * primeNum) - + (mGsmBitErrorRate * primeNum) - + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) - + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum) - + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum) - + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum) - + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum) - + (mWcdmaSignalStrength * primeNum) + (mWcdmaRscpAsu * primeNum) - + (mWcdmaRscp * primeNum) + (mIsGsm ? 1 : 0) + (mUseOnlyRsrpForLteLevel ? 1 : 0) - + (Objects.hashCode(mWcdmaDefaultSignalMeasurement)) - + (Arrays.hashCode(mLteRsrpThresholds)) + (Arrays.hashCode(mWcdmaRscpThresholds))); + return Objects.hash(mCdma, mGsm, mWcdma, mTdscdma, mLte, mLteRsrpBoost); } /** @@ -1194,40 +593,16 @@ public class SignalStrength implements Parcelable { */ @Override public boolean equals (Object o) { - SignalStrength s; + if (!(o instanceof SignalStrength)) return false; - try { - s = (SignalStrength) o; - } catch (ClassCastException ex) { - return false; - } - - if (o == null) { - return false; - } + SignalStrength s = (SignalStrength) o; - return (mGsmSignalStrength == s.mGsmSignalStrength - && mGsmBitErrorRate == s.mGsmBitErrorRate - && mCdmaDbm == s.mCdmaDbm - && mCdmaEcio == s.mCdmaEcio - && mEvdoDbm == s.mEvdoDbm - && mEvdoEcio == s.mEvdoEcio - && mEvdoSnr == s.mEvdoSnr - && mLteSignalStrength == s.mLteSignalStrength - && mLteRsrp == s.mLteRsrp - && mLteRsrq == s.mLteRsrq - && mLteRssnr == s.mLteRssnr - && mLteCqi == s.mLteCqi - && mLteRsrpBoost == s.mLteRsrpBoost - && mTdScdmaRscp == s.mTdScdmaRscp - && mWcdmaSignalStrength == s.mWcdmaSignalStrength - && mWcdmaRscpAsu == s.mWcdmaRscpAsu - && mWcdmaRscp == s.mWcdmaRscp - && mIsGsm == s.mIsGsm - && mUseOnlyRsrpForLteLevel == s.mUseOnlyRsrpForLteLevel - && Objects.equals(mWcdmaDefaultSignalMeasurement, s.mWcdmaDefaultSignalMeasurement) - && Arrays.equals(mLteRsrpThresholds, s.mLteRsrpThresholds) - && Arrays.equals(mWcdmaRscpThresholds, s.mWcdmaRscpThresholds)); + return mCdma.equals(s.mCdma) + && mGsm.equals(s.mGsm) + && mWcdma.equals(s.mWcdma) + && mTdscdma.equals(s.mTdscdma) + && mLte.equals(s.mLte) + && mLteRsrpBoost == s.mLteRsrpBoost; } /** @@ -1235,63 +610,16 @@ public class SignalStrength implements Parcelable { */ @Override public String toString() { - return ("SignalStrength:" - + " " + mGsmSignalStrength - + " " + mGsmBitErrorRate - + " " + mCdmaDbm - + " " + mCdmaEcio - + " " + mEvdoDbm - + " " + mEvdoEcio - + " " + mEvdoSnr - + " " + mLteSignalStrength - + " " + mLteRsrp - + " " + mLteRsrq - + " " + mLteRssnr - + " " + mLteCqi - + " " + mLteRsrpBoost - + " " + mTdScdmaRscp - + " " + mWcdmaSignalStrength - + " " + mWcdmaRscpAsu - + " " + mWcdmaRscp - + " " + (mIsGsm ? "gsm|lte" : "cdma") - + " " + (mUseOnlyRsrpForLteLevel ? "use_only_rsrp_for_lte_level" : - "use_rsrp_and_rssnr_for_lte_level") - + " " + mWcdmaDefaultSignalMeasurement - + " " + (Arrays.toString(mLteRsrpThresholds)) - + " " + (Arrays.toString(mWcdmaRscpThresholds))); - } - - /** Returns the signal strength related to GSM. */ - private int getGsmRelatedSignalStrength() { - int level = getLteLevel(); - if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { - level = getTdScdmaLevel(); - if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { - level = getWcdmaLevel(); - if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { - level = getGsmLevel(); - } - } - } - return level; - } - - /** Returns the signal strength related to CDMA. */ - private int getCdmaRelatedSignalStrength() { - int level; - int cdmaLevel = getCdmaLevel(); - int evdoLevel = getEvdoLevel(); - if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { - /* We don't know evdo, use cdma */ - level = cdmaLevel; - } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { - /* We don't know cdma, use evdo */ - level = evdoLevel; - } else { - /* We know both, use the lowest level */ - level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; - } - return level; + return new StringBuilder().append("SignalStrength:{") + .append("mCdma=").append(mCdma) + .append(",mGsm=").append(mGsm) + .append(",mWcdma=").append(mWcdma) + .append(",mTdscdma=").append(mTdscdma) + .append(",mLte=").append(mLte) + .append(",mLteRsrpBoost=").append(mLteRsrpBoost) + .append(",primary=").append(getPrimary().getClass().getSimpleName()) + .append("}") + .toString(); } /** @@ -1302,34 +630,13 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage private void setFromNotifierBundle(Bundle m) { - mGsmSignalStrength = m.getInt("GsmSignalStrength"); - mGsmBitErrorRate = m.getInt("GsmBitErrorRate"); - mCdmaDbm = m.getInt("CdmaDbm"); - mCdmaEcio = m.getInt("CdmaEcio"); - mEvdoDbm = m.getInt("EvdoDbm"); - mEvdoEcio = m.getInt("EvdoEcio"); - mEvdoSnr = m.getInt("EvdoSnr"); - mLteSignalStrength = m.getInt("LteSignalStrength"); - mLteRsrp = m.getInt("LteRsrp"); - mLteRsrq = m.getInt("LteRsrq"); - mLteRssnr = m.getInt("LteRssnr"); - mLteCqi = m.getInt("LteCqi"); + mCdma = m.getParcelable("Cdma"); + mGsm = m.getParcelable("Gsm"); + mWcdma = m.getParcelable("Wcdma"); + mTdscdma = m.getParcelable("Tdscdma"); + mLte = m.getParcelable("Lte"); + mLteRsrpBoost = m.getInt("LteRsrpBoost"); - mTdScdmaRscp = m.getInt("TdScdma"); - mWcdmaSignalStrength = m.getInt("WcdmaSignalStrength"); - mWcdmaRscpAsu = m.getInt("WcdmaRscpAsu"); - mWcdmaRscp = m.getInt("WcdmaRscp"); - mIsGsm = m.getBoolean("IsGsm"); - mUseOnlyRsrpForLteLevel = m.getBoolean("UseOnlyRsrpForLteLevel"); - mWcdmaDefaultSignalMeasurement = m.getString("WcdmaDefaultSignalMeasurement"); - ArrayList<Integer> lteRsrpThresholds = m.getIntegerArrayList("lteRsrpThresholds"); - for (int i = 0; i < lteRsrpThresholds.size(); i++) { - mLteRsrpThresholds[i] = lteRsrpThresholds.get(i); - } - ArrayList<Integer> wcdmaRscpThresholds = m.getIntegerArrayList("wcdmaRscpThresholds"); - for (int i = 0; i < wcdmaRscpThresholds.size(); i++) { - mWcdmaRscpThresholds[i] = wcdmaRscpThresholds.get(i); - } } /** @@ -1340,56 +647,13 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public void fillInNotifierBundle(Bundle m) { - m.putInt("GsmSignalStrength", mGsmSignalStrength); - m.putInt("GsmBitErrorRate", mGsmBitErrorRate); - m.putInt("CdmaDbm", mCdmaDbm); - m.putInt("CdmaEcio", mCdmaEcio); - m.putInt("EvdoDbm", mEvdoDbm); - m.putInt("EvdoEcio", mEvdoEcio); - m.putInt("EvdoSnr", mEvdoSnr); - m.putInt("LteSignalStrength", mLteSignalStrength); - m.putInt("LteRsrp", mLteRsrp); - m.putInt("LteRsrq", mLteRsrq); - m.putInt("LteRssnr", mLteRssnr); - m.putInt("LteCqi", mLteCqi); - m.putInt("LteRsrpBoost", mLteRsrpBoost); - m.putInt("TdScdma", mTdScdmaRscp); - m.putInt("WcdmaSignalStrength", mWcdmaSignalStrength); - m.putInt("WcdmaRscpAsu", mWcdmaRscpAsu); - m.putInt("WcdmaRscp", mWcdmaRscp); - m.putBoolean("IsGsm", mIsGsm); - m.putBoolean("UseOnlyRsrpForLteLevel", mUseOnlyRsrpForLteLevel); - m.putString("WcdmaDefaultSignalMeasurement", mWcdmaDefaultSignalMeasurement); - ArrayList<Integer> lteRsrpThresholds = new ArrayList<Integer>(); - for (int value : mLteRsrpThresholds) { - lteRsrpThresholds.add(value); - } - m.putIntegerArrayList("lteRsrpThresholds", lteRsrpThresholds); - ArrayList<Integer> wcdmaRscpThresholds = new ArrayList<Integer>(); - for (int value : mWcdmaRscpThresholds) { - wcdmaRscpThresholds.add(value); - } - m.putIntegerArrayList("wcdmaRscpThresholds", wcdmaRscpThresholds); - } + m.putParcelable("Cdma", mCdma); + m.putParcelable("Gsm", mGsm); + m.putParcelable("Wcdma", mWcdma); + m.putParcelable("Tdscdma", mTdscdma); + m.putParcelable("Lte", mLte); - /** - * Gets the default threshold array for determining the display level of LTE signal bar. - * - * @return int array for determining the display level. - */ - private int[] getDefaultLteRsrpThresholds() { - return CarrierConfigManager.getDefaultConfig().getIntArray( - CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY); - } - - /** - * Gets the default threshold array for determining the display level of WCDMA signal bar. - * - * @return int array for determining the display level. - */ - private int[] getDefaultWcdmaRscpThresholds() { - return CarrierConfigManager.getDefaultConfig().getIntArray( - CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY); + m.putInt("LteRsrpBoost", mLteRsrpBoost); } /** diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 1b37bad65d57..1378bb004696 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.BaseBundle; +import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; @@ -89,7 +90,7 @@ public final class SmsManager { new ArrayMap<Integer, SmsManager>(); /** A concrete subscription id, or the pseudo DEFAULT_SUBSCRIPTION_ID */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mSubId; /* diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index f241d45bf1e2..4598afaa41ce 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -3196,6 +3196,29 @@ public class TelephonyManager { } /** + * Gets information about currently inserted UICCs and eUICCs. See {@link UiccCardInfo} for more + * details on the kind of information available. + * + * @return UiccCardInfo an array of UiccCardInfo objects, representing information on the + * currently inserted UICCs and eUICCs. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public UiccCardInfo[] getUiccCardsInfo() { + try { + ITelephony telephony = getITelephony(); + if (telephony == null) { + return null; + } + return telephony.getUiccCardsInfo(); + } catch (RemoteException e) { + return null; + } + } + + /** * Gets all the UICC slots. The objects in the array can be null if the slot info is not * available, which is possible between phone process starting and getting slot info from modem. * @@ -6194,191 +6217,252 @@ public class TelephonyManager { NETWORK_MODE_LTE_TDSCDMA_WCDMA, NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA, NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA, - NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA + NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA, + NETWORK_MODE_NR_ONLY, + NETWORK_MODE_NR_LTE, + NETWORK_MODE_NR_LTE_CDMA_EVDO, + NETWORK_MODE_NR_LTE_GSM_WCDMA, + NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA, + NETWORK_MODE_NR_LTE_WCDMA, + NETWORK_MODE_NR_LTE_TDSCDMA, + NETWORK_MODE_NR_LTE_TDSCDMA_GSM, + NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA, + NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA, + NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA }) @Retention(RetentionPolicy.SOURCE) public @interface PrefNetworkMode{} /** - * preferred network mode is GSM/WCDMA (WCDMA preferred). + * Preferred network mode is GSM/WCDMA (WCDMA preferred). * @hide */ - @SystemApi public static final int NETWORK_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF; /** - * preferred network mode is GSM only. + * Preferred network mode is GSM only. * @hide */ - @SystemApi public static final int NETWORK_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY; /** - * preferred network mode is WCDMA only. + * Preferred network mode is WCDMA only. * @hide */ - @SystemApi public static final int NETWORK_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY; /** - * preferred network mode is GSM/WCDMA (auto mode, according to PRL). + * Preferred network mode is GSM/WCDMA (auto mode, according to PRL). * @hide */ - @SystemApi public static final int NETWORK_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS; /** - * preferred network mode is CDMA and EvDo (auto mode, according to PRL). + * Preferred network mode is CDMA and EvDo (auto mode, according to PRL). * @hide */ - @SystemApi public static final int NETWORK_MODE_CDMA_EVDO = RILConstants.NETWORK_MODE_CDMA; /** - * preferred network mode is CDMA only. + * Preferred network mode is CDMA only. * @hide */ - @SystemApi public static final int NETWORK_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO; /** - * preferred network mode is EvDo only. + * Preferred network mode is EvDo only. * @hide */ - @SystemApi public static final int NETWORK_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA; /** - * preferred network mode is GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL). + * Preferred network mode is GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL). * @hide */ - @SystemApi public static final int NETWORK_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL; /** - * preferred network mode is LTE, CDMA and EvDo. + * Preferred network mode is LTE, CDMA and EvDo. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_CDMA_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO; /** - * preferred network mode is LTE, GSM/WCDMA. + * Preferred network mode is LTE, GSM/WCDMA. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA; /** - * preferred network mode is LTE, CDMA, EvDo, GSM/WCDMA. + * Preferred network mode is LTE, CDMA, EvDo, GSM/WCDMA. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; /** - * preferred network mode is LTE Only. + * Preferred network mode is LTE Only. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY; /** - * preferred network mode is LTE/WCDMA. + * Preferred network mode is LTE/WCDMA. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_WCDMA = RILConstants.NETWORK_MODE_LTE_WCDMA; /** - * preferred network mode is TD-SCDMA only. + * Preferred network mode is TD-SCDMA only. * @hide */ - @SystemApi public static final int NETWORK_MODE_TDSCDMA_ONLY = RILConstants.NETWORK_MODE_TDSCDMA_ONLY; /** - * preferred network mode is TD-SCDMA and WCDMA. + * Preferred network mode is TD-SCDMA and WCDMA. * @hide */ - @SystemApi public static final int NETWORK_MODE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA; /** - * preferred network mode is TD-SCDMA and LTE. + * Preferred network mode is TD-SCDMA and LTE. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_TDSCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA; /** - * preferred network mode is TD-SCDMA and GSM. + * Preferred network mode is TD-SCDMA and GSM. * @hide */ - @SystemApi public static final int NETWORK_MODE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_TDSCDMA_GSM; /** - * preferred network mode is TD-SCDMA,GSM and LTE. + * Preferred network mode is TD-SCDMA,GSM and LTE. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; /** - * preferred network mode is TD-SCDMA, GSM/WCDMA. + * Preferred network mode is TD-SCDMA, GSM/WCDMA. * @hide */ - @SystemApi public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; /** - * preferred network mode is TD-SCDMA, WCDMA and LTE. + * Preferred network mode is TD-SCDMA, WCDMA and LTE. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; /** - * preferred network mode is TD-SCDMA, GSM/WCDMA and LTE. + * Preferred network mode is TD-SCDMA, GSM/WCDMA and LTE. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; /** - * preferred network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA. + * Preferred network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA. * @hide */ - @SystemApi public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; /** - * preferred network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo. + * Preferred network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo. * @hide */ - @SystemApi public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; /** + * Preferred network mode is NR 5G only. + * @hide + */ + public static final int NETWORK_MODE_NR_ONLY = RILConstants.NETWORK_MODE_NR_ONLY; + + /** + * Preferred network mode is NR 5G, LTE. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE = RILConstants.NETWORK_MODE_NR_LTE; + + /** + * Preferred network mode is NR 5G, LTE, CDMA and EvDo. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO = + RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO; + + /** + * Preferred network mode is NR 5G, LTE, GSM and WCDMA. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_GSM_WCDMA = + RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA; + + /** + * Preferred network mode is NR 5G, LTE, CDMA, EvDo, GSM and WCDMA. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA; + + /** + * Preferred network mode is NR 5G, LTE and WCDMA. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_WCDMA = RILConstants.NETWORK_MODE_NR_LTE_WCDMA; + + /** + * Preferred network mode is NR 5G, LTE and TDSCDMA. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_TDSCDMA = RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA; + + /** + * Preferred network mode is NR 5G, LTE, TD-SCDMA and GSM. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_TDSCDMA_GSM = + RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM; + + /** + * Preferred network mode is NR 5G, LTE, TD-SCDMA, WCDMA. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA = + RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA; + + /** + * Preferred network mode is NR 5G, LTE, TD-SCDMA, GSM and WCDMA. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA = + RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA; + + /** + * Preferred network mode is NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA. + * @hide + */ + public static final int NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; + + /** * Get the preferred network type. * Used for device configuration by some CDMA operators. * * <p>Requires Permission: - * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} * app has carrier privileges (see {@link #hasCarrierPrivileges}). * * @return the preferred network type. * @hide */ - @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE)) - @SystemApi + @RequiresPermission((android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)) + @UnsupportedAppUsage public @PrefNetworkMode int getPreferredNetworkType(int subId) { try { ITelephony telephony = getITelephony(); @@ -7995,7 +8079,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setSimOperatorNameForPhone(int phoneId, String name) { setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, name); @@ -8016,7 +8100,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setSimCountryIsoForPhone(int phoneId, String iso) { setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso); @@ -8037,7 +8121,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setSimStateForPhone(int phoneId, String state) { setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_SIM_STATE, state); @@ -8143,7 +8227,7 @@ public class TelephonyManager { * @param version baseband version * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setBasebandVersionForPhone(int phoneId, String version) { setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_BASEBAND_VERSION, version); } @@ -8209,7 +8293,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setPhoneType(int phoneId, int type) { if (SubscriptionManager.isValidPhoneId(phoneId)) { TelephonyManager.setTelephonyProperty(phoneId, @@ -8239,7 +8323,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String getOtaSpNumberSchemaForPhone(int phoneId, String defaultValue) { if (SubscriptionManager.isValidPhoneId(phoneId)) { return TelephonyManager.getTelephonyProperty(phoneId, diff --git a/telephony/java/android/telephony/UiccCardInfo.aidl b/telephony/java/android/telephony/UiccCardInfo.aidl new file mode 100644 index 000000000000..882c2333909f --- /dev/null +++ b/telephony/java/android/telephony/UiccCardInfo.aidl @@ -0,0 +1,19 @@ +/* + * 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 android.telephony; + +parcelable UiccCardInfo; diff --git a/telephony/java/android/telephony/UiccCardInfo.java b/telephony/java/android/telephony/UiccCardInfo.java new file mode 100644 index 000000000000..45e4704e8894 --- /dev/null +++ b/telephony/java/android/telephony/UiccCardInfo.java @@ -0,0 +1,156 @@ +/* + * 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 android.telephony; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * The UiccCardInfo represents information about a currently inserted UICC or embedded eUICC. + * @hide + */ +@SystemApi +public class UiccCardInfo implements Parcelable { + + private final boolean mIsEuicc; + private final int mCardId; + private final String mEid; + private final String mIccId; + private final int mSlotIndex; + + public static final Creator<UiccCardInfo> CREATOR = new Creator<UiccCardInfo>() { + @Override + public UiccCardInfo createFromParcel(Parcel in) { + return new UiccCardInfo(in); + } + + @Override + public UiccCardInfo[] newArray(int size) { + return new UiccCardInfo[size]; + } + }; + + private UiccCardInfo(Parcel in) { + mIsEuicc = in.readByte() != 0; + mCardId = in.readInt(); + mEid = in.readString(); + mIccId = in.readString(); + mSlotIndex = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByte((byte) (mIsEuicc ? 1 : 0)); + dest.writeInt(mCardId); + dest.writeString(mEid); + dest.writeString(mIccId); + dest.writeInt(mSlotIndex); + } + + @Override + public int describeContents() { + return 0; + } + + public UiccCardInfo(boolean isEuicc, int cardId, String eid, String iccId, int slotIndex) { + this.mIsEuicc = isEuicc; + this.mCardId = cardId; + this.mEid = eid; + this.mIccId = iccId; + this.mSlotIndex = slotIndex; + } + + /** + * Return whether the UiccCardInfo is an eUICC. + * @return true if the UICC is an eUICC. + */ + public boolean isEuicc() { + return mIsEuicc; + } + + /** + * Get the card ID of the UICC. See {@link TelephonyManager#getCardIdForDefaultEuicc()} for more + * details on card ID. + */ + public int getCardId() { + return mCardId; + } + + /** + * Get the embedded ID (EID) of the eUICC. If the UiccCardInfo is not an eUICC + * (see {@link #isEuicc()}), returns null. + */ + public String getEid() { + if (!mIsEuicc) { + return null; + } + return mEid; + } + + /** + * Get the ICCID of the UICC. + */ + public String getIccId() { + return mIccId; + } + + /** + * Gets the slot index for the slot that the UICC is currently inserted in. + */ + public int getSlotIndex() { + return mSlotIndex; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + UiccCardInfo that = (UiccCardInfo) obj; + return ((mIsEuicc == that.mIsEuicc) + && (mCardId == that.mCardId) + && (Objects.equals(mEid, that.mEid)) + && (Objects.equals(mIccId, that.mIccId)) + && (mSlotIndex == that.mSlotIndex)); + } + + @Override + public int hashCode() { + return Objects.hash(mIsEuicc, mCardId, mEid, mIccId, mSlotIndex); + } + + @Override + public String toString() { + return "UiccCardInfo (mIsEuicc=" + + mIsEuicc + + ", mCardId=" + + mCardId + + ", mEid=" + + mEid + + ", mIccId=" + + mIccId + + ", mSlotIndex=" + + mSlotIndex + + ")"; + } +} diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java index cf961d0be10c..d0b751981c28 100644 --- a/telephony/java/android/telephony/VoLteServiceState.java +++ b/telephony/java/android/telephony/VoLteServiceState.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -80,7 +81,7 @@ public final class VoLteServiceState implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public VoLteServiceState(int srvccState) { initialize(); diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java index ee602c06f0f7..45b1e474b93d 100644 --- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java +++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java @@ -17,6 +17,7 @@ package android.telephony.cdma; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Bundle; import android.telephony.CellLocation; @@ -24,7 +25,7 @@ import android.telephony.CellLocation; * Represents the cell location on a CDMA phone. */ public class CdmaCellLocation extends CellLocation { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mBaseStationId = -1; /** @@ -38,7 +39,7 @@ public class CdmaCellLocation extends CellLocation { * to 1296000, both values inclusive (corresponding to a range of -90 * to +90 degrees). Integer.MAX_VALUE is considered invalid value. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mBaseStationLatitude = INVALID_LAT_LONG; /** @@ -47,12 +48,12 @@ public class CdmaCellLocation extends CellLocation { * to 2592000, both values inclusive (corresponding to a range of -180 * to +180 degrees). Integer.MAX_VALUE is considered invalid value. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mBaseStationLongitude = INVALID_LAT_LONG; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mSystemId = -1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mNetworkId = -1; /** @@ -206,7 +207,7 @@ public class CdmaCellLocation extends CellLocation { * @param b second obj * @return true if two objects equal or both are null */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static boolean equalsHandlesNulls(Object a, Object b) { return (a == null) ? (b == null) : a.equals (b); } diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java index 98ce33368ca6..d6780ce107c9 100644 --- a/telephony/java/android/telephony/gsm/GsmCellLocation.java +++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java @@ -17,6 +17,7 @@ package android.telephony.gsm; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Bundle; import android.telephony.CellLocation; @@ -92,7 +93,7 @@ public class GsmCellLocation extends CellLocation { * Set the primary scrambling code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setPsc(int psc) { mPsc = psc; } diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index a6c24bf4e18a..cb6fcd7b62c2 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -262,6 +262,8 @@ public final class ImsCallProfile implements Parcelable { public static final String EXTRA_DISPLAY_TEXT = "DisplayText"; public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; public static final String EXTRA_IS_CALL_PULL = "CallPull"; + public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = + "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS"; /** * Extra key which the RIL can use to indicate the radio technology used for a call. diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 0fdca5d24a20..96f7a1bc22a0 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -24,7 +24,7 @@ public class DctConstants { /** * IDLE: ready to start data connection setup, default state * CONNECTING: state of issued startPppd() but not finish yet - * SCANNING: data connection fails with one apn but other apns are available + * RETRYING: data connection fails with one apn but other apns are available * ready to start data connection on other apns (before INITING) * CONNECTED: IP connection is setup * DISCONNECTING: Connection.disconnect() has been called, but PDP @@ -34,19 +34,16 @@ public class DctConstants { * * getDataConnectionState() maps State to DataState * FAILED or IDLE : DISCONNECTED - * RETRYING or CONNECTING or SCANNING: CONNECTING + * RETRYING or CONNECTING: CONNECTING * CONNECTED : CONNECTED or DISCONNECTING */ public enum State { IDLE, CONNECTING, - SCANNING, + RETRYING, CONNECTED, DISCONNECTING, FAILED, - RETRYING // After moving retry manager to ApnContext, we'll never enter this state! - // Todo: Remove this state and other places that use this state and then - // rename SCANNING to RETRYING. } public enum Activity { @@ -81,7 +78,6 @@ public class DctConstants { public static final int EVENT_RESTART_RADIO = BASE + 26; public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 29; public static final int EVENT_ICC_CHANGED = BASE + 33; - public static final int EVENT_DISCONNECT_DC_RETRYING = BASE + 34; public static final int EVENT_DATA_SETUP_COMPLETE_ERROR = BASE + 35; public static final int CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA = BASE + 36; public static final int CMD_ENABLE_MOBILE_PROVISIONING = BASE + 37; diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java index 69ff329e2d07..84c0e6453104 100644 --- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java +++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java @@ -21,6 +21,7 @@ import android.text.TextUtils; import android.util.SparseIntArray; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.telephony.Rlog; import java.nio.ByteBuffer; @@ -587,7 +588,7 @@ public class GsmAlphabet { * Additionally, in some country(ex. Korea), there are non-ASCII or MBCS characters. * If a character set is given, characters in data are treat as MBCS. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static String gsm8BitUnpackedToString(byte[] data, int offset, int length, String characterset) { boolean isMbcs = false; diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 399e2553804b..c5d82c5949f0 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -56,6 +56,7 @@ import com.android.internal.telephony.OperatorInfo; import java.util.List; import java.util.Map; +import android.telephony.UiccCardInfo; import android.telephony.UiccSlotInfo; /** @@ -1494,6 +1495,17 @@ interface ITelephony { int getCardIdForDefaultEuicc(int subId, String callingPackage); /** + * Gets information about currently inserted UICCs and eUICCs. See {@link UiccCardInfo} for more + * details on the kind of information available. + * + * @return UiccCardInfo an array of UiccCardInfo objects, representing information on the + * currently inserted UICCs and eUICCs. + * + * @hide + */ + UiccCardInfo[] getUiccCardsInfo(); + + /** * Get slot info for all the UICC slots. * @return UiccSlotInfo array. * @hide diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java index a47e2b026021..59c39b158387 100644 --- a/telephony/java/com/android/internal/telephony/OperatorInfo.java +++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -91,7 +92,7 @@ public class OperatorInfo implements Parcelable { operatorNumeric, rilStateToState(stateString)); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public OperatorInfo(String operatorAlphaLong, String operatorAlphaShort, String operatorNumeric) { diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 2ebe87067be3..1c103a9fc747 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -128,32 +128,108 @@ public interface RILConstants { int OEM_ERROR_25 = 525; /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */ - int NETWORK_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */ - int NETWORK_MODE_GSM_ONLY = 1; /* GSM only */ - int NETWORK_MODE_WCDMA_ONLY = 2; /* WCDMA only */ - int NETWORK_MODE_GSM_UMTS = 3; /* GSM/WCDMA (auto mode, according to PRL) - AVAILABLE Application Settings menu*/ - int NETWORK_MODE_CDMA = 4; /* CDMA and EvDo (auto mode, according to PRL) - AVAILABLE Application Settings menu*/ - int NETWORK_MODE_CDMA_NO_EVDO = 5; /* CDMA only */ - int NETWORK_MODE_EVDO_NO_CDMA = 6; /* EvDo only */ - int NETWORK_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) - AVAILABLE Application Settings menu*/ - int NETWORK_MODE_LTE_CDMA_EVDO = 8; /* LTE, CDMA and EvDo */ - int NETWORK_MODE_LTE_GSM_WCDMA = 9; /* LTE, GSM/WCDMA */ - int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */ - int NETWORK_MODE_LTE_ONLY = 11; /* LTE Only mode. */ - int NETWORK_MODE_LTE_WCDMA = 12; /* LTE/WCDMA */ - int NETWORK_MODE_TDSCDMA_ONLY = 13; /* TD-SCDMA only */ - int NETWORK_MODE_TDSCDMA_WCDMA = 14; /* TD-SCDMA and WCDMA */ - int NETWORK_MODE_LTE_TDSCDMA = 15; /* TD-SCDMA and LTE */ - int NETWORK_MODE_TDSCDMA_GSM = 16; /* TD-SCDMA and GSM */ - int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; /* TD-SCDMA,GSM and LTE */ - int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; /* TD-SCDMA, GSM/WCDMA */ - int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; /* TD-SCDMA, WCDMA and LTE */ - int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; /* TD-SCDMA, GSM/WCDMA and LTE */ - int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/ - int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */ + /** GSM, WCDMA (WCDMA preferred) */ + int NETWORK_MODE_WCDMA_PREF = 0; + + /** GSM only */ + int NETWORK_MODE_GSM_ONLY = 1; + + /** WCDMA only */ + int NETWORK_MODE_WCDMA_ONLY = 2; + + /** GSM, WCDMA (auto mode, according to PRL) */ + int NETWORK_MODE_GSM_UMTS = 3; + + /** CDMA and EvDo (auto mode, according to PRL) */ + int NETWORK_MODE_CDMA = 4; + + /** CDMA only */ + int NETWORK_MODE_CDMA_NO_EVDO = 5; + + /** EvDo only */ + int NETWORK_MODE_EVDO_NO_CDMA = 6; + + /** GSM, WCDMA, CDMA, and EvDo (auto mode, according to PRL) */ + int NETWORK_MODE_GLOBAL = 7; + + /** LTE, CDMA and EvDo */ + int NETWORK_MODE_LTE_CDMA_EVDO = 8; + + /** LTE, GSM and WCDMA */ + int NETWORK_MODE_LTE_GSM_WCDMA = 9; + + /** LTE, CDMA, EvDo, GSM, and WCDMA */ + int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; + + /** LTE only mode. */ + int NETWORK_MODE_LTE_ONLY = 11; + + /** LTE and WCDMA */ + int NETWORK_MODE_LTE_WCDMA = 12; + + /** TD-SCDMA only */ + int NETWORK_MODE_TDSCDMA_ONLY = 13; + + /** TD-SCDMA and WCDMA */ + int NETWORK_MODE_TDSCDMA_WCDMA = 14; + + /** LTE and TD-SCDMA*/ + int NETWORK_MODE_LTE_TDSCDMA = 15; + + /** TD-SCDMA and GSM */ + int NETWORK_MODE_TDSCDMA_GSM = 16; + + /** TD-SCDMA, GSM and LTE */ + int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; + + /** TD-SCDMA, GSM and WCDMA */ + int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; + + /** LTE, TD-SCDMA and WCDMA */ + int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; + + /** LTE, TD-SCDMA, GSM, and WCDMA */ + int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; + + /** TD-SCDMA, CDMA, EVDO, GSM and WCDMA */ + int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; + + /** LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA */ + int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; + + /** NR 5G only mode */ + int NETWORK_MODE_NR_ONLY = 23; + + /** NR 5G, LTE */ + int NETWORK_MODE_NR_LTE = 24; + + /** NR 5G, LTE, CDMA and EvDo */ + int NETWORK_MODE_NR_LTE_CDMA_EVDO = 25; + + /** NR 5G, LTE, GSM and WCDMA */ + int NETWORK_MODE_NR_LTE_GSM_WCDMA = 26; + + /** NR 5G, LTE, CDMA, EvDo, GSM and WCDMA */ + int NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA = 27; + + /** NR 5G, LTE and WCDMA */ + int NETWORK_MODE_NR_LTE_WCDMA = 28; + + /** NR 5G, LTE and TDSCDMA */ + int NETWORK_MODE_NR_LTE_TDSCDMA = 29; + + /** NR 5G, LTE, TD-SCDMA and GSM */ + int NETWORK_MODE_NR_LTE_TDSCDMA_GSM = 30; + + /** NR 5G, LTE, TD-SCDMA, WCDMA */ + int NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA = 31; + + /** NR 5G, LTE, TD-SCDMA, GSM and WCDMA */ + int NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA = 32; + + /** NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA */ + int NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 33; + int PREFERRED_NETWORK_MODE = Integer.parseInt(TelephonyManager.getTelephonyProperty(0, "ro.telephony.default_network", Integer.toString(NETWORK_MODE_WCDMA_PREF))); @@ -422,6 +498,7 @@ public interface RILConstants { int RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA = 203; int RIL_REQUEST_SET_PREFERRED_DATA_MODEM = 204; int RIL_REQUEST_EMERGENCY_DIAL = 205; + int RIL_REQUEST_GET_PHONE_CAPABILITY = 206; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index 7b1ead9722b8..190eac4d8c02 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -23,6 +23,7 @@ import java.text.BreakIterator; import java.util.Arrays; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.provider.Telephony; import android.telephony.SmsMessage; import android.text.Emoji; @@ -118,7 +119,7 @@ public abstract class SmsMessageBase { * Returns the address of the SMS service center that relayed this message * or null if there is none. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String getServiceCenterAddress() { return mScAddress; } @@ -223,14 +224,14 @@ public abstract class SmsMessageBase { /** * Get protocol identifier. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public abstract int getProtocolIdentifier(); /** * See TS 23.040 9.2.3.9 returns true if this is a "replace short message" * SMS */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public abstract boolean isReplace(); /** @@ -302,7 +303,7 @@ public abstract class SmsMessageBase { * See TS 23.040, 9.9.2.3.15 for a description of other possible * values. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public abstract int getStatus(); /** @@ -315,7 +316,7 @@ public abstract class SmsMessageBase { * Returns true iff the <code>TP-Reply-Path</code> bit is set in * this message. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public abstract boolean isReplyPathPresent(); /** diff --git a/test-mock/src/android/test/mock/MockPackageManager.java b/test-mock/src/android/test/mock/MockPackageManager.java index 89734e35c13f..226c0b8c07d6 100644 --- a/test-mock/src/android/test/mock/MockPackageManager.java +++ b/test-mock/src/android/test/mock/MockPackageManager.java @@ -18,8 +18,6 @@ package android.test.mock; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UserIdInt; -import android.app.PackageInstallObserver; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; @@ -52,7 +50,6 @@ import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.Handler; import android.os.PersistableBundle; import android.os.UserHandle; diff --git a/tests/ActivityViewTest/src/com/google/android/test/activityview/ActivityViewActivity.java b/tests/ActivityViewTest/src/com/google/android/test/activityview/ActivityViewActivity.java index 1548d6ed8a03..f7c60fc73cb3 100644 --- a/tests/ActivityViewTest/src/com/google/android/test/activityview/ActivityViewActivity.java +++ b/tests/ActivityViewTest/src/com/google/android/test/activityview/ActivityViewActivity.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.ActivityView; import android.content.Intent; import android.os.Bundle; +import android.os.Parcelable; import android.widget.Button; public class ActivityViewActivity extends Activity { @@ -41,6 +42,10 @@ public class ActivityViewActivity extends Activity { final Intent intent = Intent.makeMainActivity(null); final Intent chooser = Intent.createChooser(intent, "Pick an app to launch in ActivityView"); + chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[] { + new Intent(Intent.ACTION_MAIN) + .addCategory("com.android.internal.category.PLATLOGO") + }); if (intent.resolveActivity(getPackageManager()) != null) { chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); diff --git a/tests/RollbackTest/Android.mk b/tests/RollbackTest/Android.mk new file mode 100644 index 000000000000..f2bd40761e08 --- /dev/null +++ b/tests/RollbackTest/Android.mk @@ -0,0 +1,54 @@ +# 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. + +LOCAL_PATH:= $(call my-dir) + +# RollbackTestAppV1 +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) +LOCAL_MANIFEST_FILE := TestApp/AndroidManifestV1.xml +LOCAL_PACKAGE_NAME := RollbackTestAppV1 +LOCAL_SDK_VERSION := current +LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src) +include $(BUILD_PACKAGE) +ROLLBACK_TEST_APP_V1 := $(LOCAL_INSTALLED_MODULE) + +# RollbackTestAppV2 +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) +LOCAL_MANIFEST_FILE := TestApp/AndroidManifestV2.xml +LOCAL_PACKAGE_NAME := RollbackTestAppV2 +LOCAL_SDK_VERSION := current +LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src) +include $(BUILD_PACKAGE) +ROLLBACK_TEST_APP_V2 := $(LOCAL_INSTALLED_MODULE) + +# RollbackTest +include $(CLEAR_VARS) +LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_PACKAGE_NAME := RollbackTest +LOCAL_MODULE_TAGS := tests +LOCAL_STATIC_JAVA_LIBRARIES := android-support-test +LOCAL_COMPATIBILITY_SUITE := general-tests +LOCAL_CERTIFICATE := platform +LOCAL_JAVA_RESOURCE_FILES := $(ROLLBACK_TEST_APP_V1) $(ROLLBACK_TEST_APP_V2) +LOCAL_SDK_VERSION := test_current +LOCAL_TEST_CONFIG := RollbackTest.xml +include $(BUILD_PACKAGE) + +# Clean up local variables +ROLLBACK_TEST_APP_V1 := +ROLLBACK_TEST_APP_V2 := diff --git a/tests/RollbackTest/AndroidManifest.xml b/tests/RollbackTest/AndroidManifest.xml new file mode 100644 index 000000000000..d1535a3bbc74 --- /dev/null +++ b/tests/RollbackTest/AndroidManifest.xml @@ -0,0 +1,34 @@ +<?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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.rollback" > + + <uses-permission android:name="android.permission.INSTALL_PACKAGES" /> + <uses-permission android:name="android.permission.DELETE_PACKAGES" /> + + <application> + <receiver android:name="com.android.tests.rollback.LocalIntentSender" + android:exported="true" /> + <uses-library android:name="android.test.runner" /> + </application> + + + <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.tests.rollback" + android:label="Rollback Test"/> + +</manifest> diff --git a/packages/SystemUI/res/drawable/ic_notify_button_bg.xml b/tests/RollbackTest/RollbackTest.xml index 3a47261851a5..adbad56cd934 100644 --- a/packages/SystemUI/res/drawable/ic_notify_button_bg.xml +++ b/tests/RollbackTest/RollbackTest.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 The Android Open Source Project +<!-- 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. @@ -13,8 +13,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_pressed="true" - android:drawable="@*android:drawable/list_selector_pressed_holo_dark" /> -</selector> +<configuration description="Runs the rollback tests"> + <option name="test-suite-tag" value="RollbackTest" /> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="RollbackTest.apk" /> + </target_preparer> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.tests.rollback" /> + <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + </test> +</configuration> diff --git a/tests/RollbackTest/TestApp/AndroidManifestV1.xml b/tests/RollbackTest/TestApp/AndroidManifestV1.xml new file mode 100644 index 000000000000..45e9584c14d1 --- /dev/null +++ b/tests/RollbackTest/TestApp/AndroidManifestV1.xml @@ -0,0 +1,33 @@ +<?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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.rollback.testapp" + android:versionCode="1" + android:versionName="1.0" > + + + <uses-sdk android:minSdkVersion="19" /> + + <application android:label="Rollback Test App V1"> + <activity android:name="com.android.tests.rollback.testapp.MainActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RollbackTest/TestApp/AndroidManifestV2.xml b/tests/RollbackTest/TestApp/AndroidManifestV2.xml new file mode 100644 index 000000000000..0104086c479d --- /dev/null +++ b/tests/RollbackTest/TestApp/AndroidManifestV2.xml @@ -0,0 +1,33 @@ +<?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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.rollback.testapp" + android:versionCode="2" + android:versionName="2.0" > + + + <uses-sdk android:minSdkVersion="19" /> + + <application android:label="Rollback Test App V2"> + <activity android:name="com.android.tests.rollback.testapp.MainActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java new file mode 100644 index 000000000000..1856bac0d9f9 --- /dev/null +++ b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java @@ -0,0 +1,31 @@ +/* + * 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.tests.rollback.testapp; + +import android.app.Activity; +import android.os.Bundle; + +/** + * A test app for testing apk rollback support. + */ +public class MainActivity extends Activity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } +} diff --git a/tests/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java b/tests/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java new file mode 100644 index 000000000000..ddcf1dabcafc --- /dev/null +++ b/tests/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java @@ -0,0 +1,59 @@ +/* + * 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.tests.rollback; + +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; +import android.support.test.InstrumentationRegistry; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * Make IntentSender that sends intent locally. + */ +public class LocalIntentSender extends BroadcastReceiver { + + private static final String TAG = "RollbackTest"; + + private static final BlockingQueue<Intent> sIntentSenderResults = new LinkedBlockingQueue<>(); + + @Override + public void onReceive(Context context, Intent intent) { + sIntentSenderResults.add(intent); + } + + /** + * Get a LocalIntentSender. + */ + static IntentSender getIntentSender() { + Context context = InstrumentationRegistry.getContext(); + Intent intent = new Intent(context, LocalIntentSender.class); + PendingIntent pending = PendingIntent.getBroadcast(context, 0, intent, 0); + return pending.getIntentSender(); + } + + /** + * Returns the most recent Intent sent by a LocalIntentSender. + */ + static Intent getIntentSenderResult() throws InterruptedException { + return sIntentSenderResults.take(); + } +} diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java b/tests/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java new file mode 100644 index 000000000000..d3c39f0b8248 --- /dev/null +++ b/tests/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java @@ -0,0 +1,71 @@ +/* + * 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.tests.rollback; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.test.InstrumentationRegistry; +import android.util.Log; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * A broadcast receiver that can be used to get + * ACTION_PACKAGE_ROLLBACK_EXECUTED broadcasts. + */ +class RollbackBroadcastReceiver extends BroadcastReceiver { + + private static final String TAG = "RollbackTest"; + + private final BlockingQueue<Intent> mRollbackBroadcasts = new LinkedBlockingQueue<>(); + + /** + * Creates a RollbackBroadcastReceiver and registers it with the given + * context. + */ + RollbackBroadcastReceiver() { + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_PACKAGE_ROLLBACK_EXECUTED); + filter.addDataScheme("package"); + InstrumentationRegistry.getContext().registerReceiver(this, filter); + } + + @Override + public void onReceive(Context context, Intent intent) { + Log.i(TAG, "Received rollback broadcast intent"); + mRollbackBroadcasts.add(intent); + } + + /** + * Polls for at most the given amount of time for the next rollback + * broadcast. + */ + Intent poll(long timeout, TimeUnit unit) throws InterruptedException { + return mRollbackBroadcasts.poll(timeout, unit); + } + + /** + * Unregisters this broadcast receiver. + */ + void unregister() { + InstrumentationRegistry.getContext().unregisterReceiver(this); + } +} diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java new file mode 100644 index 000000000000..02c1ce2e8b31 --- /dev/null +++ b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java @@ -0,0 +1,273 @@ +/* + * 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.tests.rollback; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.rollback.RollbackInfo; +import android.content.rollback.RollbackManager; +import android.net.Uri; +import android.support.test.InstrumentationRegistry; +import android.util.Log; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +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.junit.Assert.fail; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.concurrent.TimeUnit; + +/** + * Test system Rollback APIs. + * TODO: Should this be a cts test instead? Where should it live? + */ +@RunWith(JUnit4.class) +public class RollbackTest { + + private static final String TAG = "RollbackTest"; + + private static final String TEST_APP_PACKAGE_NAME = "com.android.tests.rollback.testapp"; + + /** + * Test basic rollbacks. + */ + @Test + public void testBasic() throws Exception { + // Make sure an app can't listen to or disturb the internal + // ACTION_PACKAGE_ENABLE_ROLLBACK broadcast. + Context context = InstrumentationRegistry.getContext(); + IntentFilter enableRollbackFilter = new IntentFilter(); + enableRollbackFilter.addAction("android.intent.action.PACKAGE_ENABLE_ROLLBACK"); + enableRollbackFilter.addDataType("application/vnd.android.package-archive"); + enableRollbackFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + BroadcastReceiver enableRollbackReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + abortBroadcast(); + } + }; + context.registerReceiver(enableRollbackReceiver, enableRollbackFilter); + + // Register a broadcast receiver for notification when the rollback is + // done executing. + RollbackBroadcastReceiver broadcastReceiver = new RollbackBroadcastReceiver(); + RollbackManager rm = RollbackTestUtils.getRollbackManager(); + + // Uninstall com.android.tests.rollback.testapp + RollbackTestUtils.uninstall("com.android.tests.rollback.testapp"); + assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME)); + + // TODO: There is currently a race condition between when the app is + // uninstalled and when rollback manager deletes the rollback. Fix it + // so that's not the case! + for (int i = 0; i < 5; ++i) { + for (RollbackInfo info : rm.getRecentlyExecutedRollbacks()) { + if (TEST_APP_PACKAGE_NAME.equals(info.targetPackage.packageName)) { + Log.i(TAG, "Sleeping 1 second to wait for uninstall to take effect."); + Thread.sleep(1000); + break; + } + } + } + + // The app should not be available for rollback. + assertNull(rm.getAvailableRollback(TEST_APP_PACKAGE_NAME)); + assertFalse(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME)); + + // There should be no recently executed rollbacks for this package. + for (RollbackInfo info : rm.getRecentlyExecutedRollbacks()) { + assertNotEquals(TEST_APP_PACKAGE_NAME, info.targetPackage.packageName); + } + + // Install v1 of the app (without rollbacks enabled). + RollbackTestUtils.install("RollbackTestAppV1.apk", false); + assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME)); + + // Upgrade from v1 to v2, with rollbacks enabled. + RollbackTestUtils.install("RollbackTestAppV2.apk", true); + assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME)); + + // The app should now be available for rollback. + assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME)); + RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME); + assertNotNull(rollback); + assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName); + assertEquals(2, rollback.targetPackage.higherVersion.versionCode); + assertEquals(1, rollback.targetPackage.lowerVersion.versionCode); + + // We should not have received any rollback requests yet. + // TODO: Possibly flaky if, by chance, some other app on device + // happens to be rolled back at the same time? + assertNull(broadcastReceiver.poll(0, TimeUnit.SECONDS)); + + // Roll back the app. + RollbackTestUtils.rollback(rollback); + assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME)); + + // Verify we received a broadcast for the rollback. + // TODO: Race condition between the timeout and when the broadcast is + // received could lead to test flakiness. + Intent broadcast = broadcastReceiver.poll(5, TimeUnit.SECONDS); + assertNotNull(broadcast); + assertEquals(TEST_APP_PACKAGE_NAME, broadcast.getData().getSchemeSpecificPart()); + assertNull(broadcastReceiver.poll(0, TimeUnit.SECONDS)); + + // Verify the recent rollback has been recorded. + rollback = null; + for (RollbackInfo r : rm.getRecentlyExecutedRollbacks()) { + if (TEST_APP_PACKAGE_NAME.equals(r.targetPackage.packageName)) { + assertNull(rollback); + rollback = r; + } + } + assertNotNull(rollback); + assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName); + assertEquals(2, rollback.targetPackage.higherVersion.versionCode); + assertEquals(1, rollback.targetPackage.lowerVersion.versionCode); + + broadcastReceiver.unregister(); + context.unregisterReceiver(enableRollbackReceiver); + } + + /** + * Test that rollback data is properly persisted. + */ + @Test + public void testRollbackDataPersistence() throws Exception { + RollbackManager rm = RollbackTestUtils.getRollbackManager(); + + // Prep installation of com.android.tests.rollback.testapp + RollbackTestUtils.uninstall("com.android.tests.rollback.testapp"); + RollbackTestUtils.install("RollbackTestAppV1.apk", false); + RollbackTestUtils.install("RollbackTestAppV2.apk", true); + assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME)); + + // The app should now be available for rollback. + assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME)); + RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME); + assertNotNull(rollback); + assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName); + assertEquals(2, rollback.targetPackage.higherVersion.versionCode); + assertEquals(1, rollback.targetPackage.lowerVersion.versionCode); + + // Reload the persisted data. + rm.reloadPersistedData(); + + // The app should still be available for rollback. + assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME)); + rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME); + assertNotNull(rollback); + assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName); + assertEquals(2, rollback.targetPackage.higherVersion.versionCode); + assertEquals(1, rollback.targetPackage.lowerVersion.versionCode); + + // Roll back the app. + RollbackTestUtils.rollback(rollback); + assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME)); + + // Verify the recent rollback has been recorded. + rollback = null; + for (RollbackInfo r : rm.getRecentlyExecutedRollbacks()) { + if (TEST_APP_PACKAGE_NAME.equals(r.targetPackage.packageName)) { + assertNull(rollback); + rollback = r; + } + } + assertNotNull(rollback); + assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName); + assertEquals(2, rollback.targetPackage.higherVersion.versionCode); + assertEquals(1, rollback.targetPackage.lowerVersion.versionCode); + + // Reload the persisted data. + rm.reloadPersistedData(); + + // Verify the recent rollback is still recorded. + rollback = null; + for (RollbackInfo r : rm.getRecentlyExecutedRollbacks()) { + if (TEST_APP_PACKAGE_NAME.equals(r.targetPackage.packageName)) { + assertNull(rollback); + rollback = r; + } + } + assertNotNull(rollback); + assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName); + assertEquals(2, rollback.targetPackage.higherVersion.versionCode); + assertEquals(1, rollback.targetPackage.lowerVersion.versionCode); + } + + /** + * Test explicit expiration of rollbacks. + * Does not test the scheduling aspects of rollback expiration. + */ + @Test + public void testRollbackExpiration() throws Exception { + RollbackManager rm = RollbackTestUtils.getRollbackManager(); + RollbackTestUtils.uninstall("com.android.tests.rollback.testapp"); + RollbackTestUtils.install("RollbackTestAppV1.apk", false); + RollbackTestUtils.install("RollbackTestAppV2.apk", true); + assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME)); + + // The app should now be available for rollback. + assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME)); + RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME); + assertNotNull(rollback); + assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName); + assertEquals(2, rollback.targetPackage.higherVersion.versionCode); + assertEquals(1, rollback.targetPackage.lowerVersion.versionCode); + + // Expire the rollback. + rm.expireRollbackForPackage(TEST_APP_PACKAGE_NAME); + + // The rollback should no longer be available. + assertNull(rm.getAvailableRollback(TEST_APP_PACKAGE_NAME)); + assertFalse(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME)); + } + + /** + * Test restrictions on rollback broadcast sender. + * A random app should not be able to send a PACKAGE_ROLLBACK_EXECUTED broadcast. + */ + @Test + public void testRollbackBroadcastRestrictions() throws Exception { + RollbackBroadcastReceiver broadcastReceiver = new RollbackBroadcastReceiver(); + Intent broadcast = new Intent(Intent.ACTION_PACKAGE_ROLLBACK_EXECUTED, + Uri.fromParts("package", "com.android.tests.rollback.bogus", null)); + try { + InstrumentationRegistry.getContext().sendBroadcast(broadcast); + fail("Succeeded in sending restricted broadcast from app context."); + } catch (SecurityException se) { + // Expected behavior. + } + + // Confirm that we really haven't received the broadcast. + // TODO: How long to wait for the expected timeout? + assertNull(broadcastReceiver.poll(5, TimeUnit.SECONDS)); + + // TODO: Do we need to do this? Do we need to ensure this is always + // called, even when the test fails? + broadcastReceiver.unregister(); + } +} diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java new file mode 100644 index 000000000000..c5ce3fa46d46 --- /dev/null +++ b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java @@ -0,0 +1,153 @@ +/* + * 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.tests.rollback; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageInstaller; +import android.content.pm.PackageManager; +import android.content.rollback.RollbackInfo; +import android.content.rollback.RollbackManager; +import android.support.test.InstrumentationRegistry; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Utilities to facilitate testing rollbacks. + */ +class RollbackTestUtils { + + private static final String TAG = "RollbackTest"; + + static RollbackManager getRollbackManager() { + Context context = InstrumentationRegistry.getContext(); + RollbackManager rm = (RollbackManager) context.getSystemService(Context.ROLLBACK_SERVICE); + if (rm == null) { + throw new AssertionError("Failed to get RollbackManager"); + } + return rm; + } + + /** + * Returns the version of the given package installed on device. + * Returns -1 if the package is not currently installed. + */ + static long getInstalledVersion(String packageName) { + Context context = InstrumentationRegistry.getContext(); + PackageManager pm = context.getPackageManager(); + try { + PackageInfo info = pm.getPackageInfo(packageName, 0); + return info.getLongVersionCode(); + } catch (PackageManager.NameNotFoundException e) { + return -1; + } + } + + private static void assertStatusSuccess(Intent result) { + int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_FAILURE); + if (status == -1) { + throw new AssertionError("PENDING USER ACTION"); + } else if (status > 0) { + String message = result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE); + throw new AssertionError(message == null ? "UNKNOWN FAILURE" : message); + } + } + + /** + * Uninstalls the given package. + * Does nothing if the package is not installed. + * @throws AssertionError if package can't be uninstalled. + */ + static void uninstall(String packageName) throws InterruptedException, IOException { + // No need to uninstall if the package isn't installed. + if (getInstalledVersion(packageName) == -1) { + return; + } + + Context context = InstrumentationRegistry.getContext(); + PackageManager packageManager = context.getPackageManager(); + PackageInstaller packageInstaller = packageManager.getPackageInstaller(); + packageInstaller.uninstall(packageName, LocalIntentSender.getIntentSender()); + assertStatusSuccess(LocalIntentSender.getIntentSenderResult()); + } + + /** + * Execute the given rollback. + * @throws AssertionError if the rollback fails. + */ + static void rollback(RollbackInfo rollback) throws InterruptedException { + RollbackManager rm = getRollbackManager(); + rm.executeRollback(rollback, LocalIntentSender.getIntentSender()); + assertStatusSuccess(LocalIntentSender.getIntentSenderResult()); + } + + /** + * Installs the apk with the given name. + * + * @param resourceName name of class loader resource for the apk to + * install. + * @param enableRollback if rollback should be enabled. + * @throws AssertionError if the installation fails. + */ + static void install(String resourceName, boolean enableRollback) + throws InterruptedException, IOException { + Context context = InstrumentationRegistry.getContext(); + PackageInstaller.Session session = null; + PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); + PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( + PackageInstaller.SessionParams.MODE_FULL_INSTALL); + if (enableRollback) { + params.setEnableRollback(); + } + int sessionId = packageInstaller.createSession(params); + session = packageInstaller.openSession(sessionId); + + ClassLoader loader = RollbackTest.class.getClassLoader(); + try (OutputStream packageInSession = session.openWrite("package", 0, -1); + InputStream is = loader.getResourceAsStream(resourceName);) { + byte[] buffer = new byte[4096]; + int n; + while ((n = is.read(buffer)) >= 0) { + packageInSession.write(buffer, 0, n); + } + } + + // Commit the session (this will start the installation workflow). + session.commit(LocalIntentSender.getIntentSender()); + assertStatusSuccess(LocalIntentSender.getIntentSenderResult()); + } + + // TODO: Unused + static void adoptShellPermissionIdentity() { + InstrumentationRegistry + .getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + } + + // TODO: Unused + static void dropShellPermissionIdentity() { + InstrumentationRegistry + .getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); + } +} diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index 369a002fa273..4c2a984f8198 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -16,16 +16,16 @@ package com.android.framework.permission.tests; -import android.content.res.Configuration; +import static android.view.Display.DEFAULT_DISPLAY; + import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; import android.view.IWindowManager; -import junit.framework.TestCase; -import static android.view.Display.DEFAULT_DISPLAY; +import junit.framework.TestCase; /** * TODO: Remove this. This is only a placeholder, need to implement this. @@ -73,17 +73,6 @@ public class WindowManagerPermissionTests extends TestCase { } try { - mWm.updateOrientationFromAppTokens(new Configuration(), - null /* freezeThisOneIfNeeded */, DEFAULT_DISPLAY); - fail("IWindowManager.updateOrientationFromAppTokens did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { mWm.prepareAppTransition(0, false); fail("IWindowManager.prepareAppTransition did not throw SecurityException as" + " expected"); diff --git a/tools/incident_report/printer.h b/tools/incident_report/printer.h index ed93fa19542c..63e276b367ca 100644 --- a/tools/incident_report/printer.h +++ b/tools/incident_report/printer.h @@ -22,7 +22,7 @@ class Out { public: - Out(int fd); + explicit Out(int fd); ~Out(); void printf(const char* format, ...); diff --git a/wifi/java/android/net/wifi/DppStatusCallback.java b/wifi/java/android/net/wifi/DppStatusCallback.java new file mode 100644 index 000000000000..fa2ab30ef479 --- /dev/null +++ b/wifi/java/android/net/wifi/DppStatusCallback.java @@ -0,0 +1,166 @@ +/* + * 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 android.net.wifi; + +import android.annotation.IntDef; +import android.annotation.SystemApi; +import android.os.Handler; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * DPP Status Callback. Use this callback to get status updates (success, failure, progress) + * from the DPP operation started with {@link WifiManager#startDppAsConfiguratorInitiator(String, + * int, int, Handler, DppStatusCallback)} or {@link WifiManager#startDppAsEnrolleeInitiator(String, + * Handler, DppStatusCallback)} + * @hide + */ +@SystemApi +public abstract class DppStatusCallback { + /** + * DPP Success event: Configuration sent (Configurator mode). + */ + public static final int DPP_EVENT_SUCCESS_CONFIGURATION_SENT = 0; + + /** @hide */ + @IntDef(prefix = { "DPP_EVENT_SUCCESS_" }, value = { + DPP_EVENT_SUCCESS_CONFIGURATION_SENT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppSuccessStatusCode {} + + /** + * DPP Progress event: Initial authentication with peer succeeded. + */ + public static final int DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; + + /** + * DPP Progress event: Peer requires more time to process bootstrapping. + */ + public static final int DPP_EVENT_PROGRESS_RESPONSE_PENDING = 1; + + /** @hide */ + @IntDef(prefix = { "DPP_EVENT_PROGRESS_" }, value = { + DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS, + DPP_EVENT_PROGRESS_RESPONSE_PENDING, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppProgressStatusCode {} + + /** + * DPP Failure event: Scanned QR code is either not a DPP URI, or the DPP URI has errors. + */ + public static final int DPP_EVENT_FAILURE_INVALID_URI = -1; + + /** + * DPP Failure event: Bootstrapping/Authentication initialization process failure. + */ + public static final int DPP_EVENT_FAILURE_AUTHENTICATION = -2; + + /** + * DPP Failure event: Both devices are implementing the same role and are incompatible. + */ + public static final int DPP_EVENT_FAILURE_NOT_COMPATIBLE = -3; + + /** + * DPP Failure event: Configuration process has failed due to malformed message. + */ + public static final int DPP_EVENT_FAILURE_CONFIGURATION = -4; + + /** + * DPP Failure event: DPP request while in another DPP exchange. + */ + public static final int DPP_EVENT_FAILURE_BUSY = -5; + + /** + * DPP Failure event: No response from the peer. + */ + public static final int DPP_EVENT_FAILURE_TIMEOUT = -6; + + /** + * DPP Failure event: General protocol failure. + */ + public static final int DPP_EVENT_FAILURE = -7; + + /** + * DPP Failure event: Feature or option is not supported. + */ + public static final int DPP_EVENT_FAILURE_NOT_SUPPORTED = -8; + + /** + * DPP Failure event: Invalid network provided to DPP configurator. + * Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK). + */ + public static final int DPP_EVENT_FAILURE_INVALID_NETWORK = -9; + + + /** @hide */ + @IntDef(prefix = {"DPP_EVENT_FAILURE_"}, value = { + DPP_EVENT_FAILURE_INVALID_URI, + DPP_EVENT_FAILURE_AUTHENTICATION, + DPP_EVENT_FAILURE_NOT_COMPATIBLE, + DPP_EVENT_FAILURE_CONFIGURATION, + DPP_EVENT_FAILURE_BUSY, + DPP_EVENT_FAILURE_TIMEOUT, + DPP_EVENT_FAILURE, + DPP_EVENT_FAILURE_NOT_SUPPORTED, + DPP_EVENT_FAILURE_INVALID_NETWORK, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppFailureStatusCode { + } + + /** + * Called when local DPP Enrollee successfully receives a new Wi-Fi configuration from the + * peer DPP configurator. This callback marks the successful end of the DPP current DPP + * session, and no further callbacks will be called. This callback is the successful outcome + * of a DPP flow starting with {@link WifiManager#startDppAsEnrolleeInitiator(String, Handler, + * DppStatusCallback)}. + * + * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator + */ + public abstract void onEnrolleeSuccess(int newNetworkId); + + /** + * Called when a DPP success event takes place, except for when configuration is received from + * an external Configurator. The callback onSuccessConfigReceived will be used in this case. + * This callback marks the successful end of the current DPP session, and no further + * callbacks will be called. This callback is the successful outcome of a DPP flow starting with + * {@link WifiManager#startDppAsConfiguratorInitiator(String, int, int, Handler, + * DppStatusCallback)}. + * + * @param code DPP success status code. + */ + public abstract void onConfiguratorSuccess(@DppSuccessStatusCode int code); + + /** + * Called when a DPP Failure event takes place. This callback marks the unsuccessful end of the + * current DPP session, and no further callbacks will be called. + * + * @param code DPP failure status code. + */ + public abstract void onFailure(@DppFailureStatusCode int code); + + /** + * Called when DPP events that indicate progress take place. Can be used by UI elements + * to show progress. + * + * @param code DPP progress status code. + */ + public abstract void onProgress(@DppProgressStatusCode int code); +} diff --git a/wifi/java/android/net/wifi/IDppCallback.aidl b/wifi/java/android/net/wifi/IDppCallback.aidl new file mode 100644 index 000000000000..c452c7664c12 --- /dev/null +++ b/wifi/java/android/net/wifi/IDppCallback.aidl @@ -0,0 +1,48 @@ +/* + * 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 android.net.wifi; + +/** + * Interface for DPP callback. + * + * @hide + */ +oneway interface IDppCallback +{ + /** + * Called when local DPP Enrollee successfully receives a new Wi-Fi configuratrion from the + * peer DPP configurator. + */ + void onSuccessConfigReceived(int newNetworkId); + + /** + * Called when DPP success events take place, except for when configuration is received from + * an external Configurator. The callback onSuccessConfigReceived will be used in this case. + */ + void onSuccess(int status); + + /** + * Called when DPP Failure events take place. + */ + void onFailure(int status); + + /** + * Called when DPP events that indicate progress take place. Can be used by UI elements + * to show progress. + */ + void onProgress(int status); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 0362a1b491ea..1700006f939d 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -25,6 +25,7 @@ import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.DhcpInfo; import android.net.Network; +import android.net.wifi.IDppCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; @@ -199,5 +200,13 @@ interface IWifiManager String[] getFactoryMacAddresses(); void setDeviceMobilityState(int state); + + void startDppAsConfiguratorInitiator(in IBinder binder, in String enrolleeUri, + int selectedNetworkId, int netRole, in IDppCallback callback); + + void startDppAsEnrolleeInitiator(in IBinder binder, in String configuratorUri, + in IDppCallback callback); + + void stopDppSession(); } diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 64f8adb36a93..a809cad74e07 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -28,6 +28,7 @@ import android.net.ProxyInfo; import android.net.StaticIpConfiguration; import android.net.Uri; import android.net.wifi.WifiInfo; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -632,7 +633,7 @@ public class WifiConfiguration implements Parcelable { * the network we need to be before autojoin kicks in */ /** @hide **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static int INVALID_RSSI = -127; // States for the userApproved field @@ -708,6 +709,12 @@ public class WifiConfiguration implements Parcelable { } /** + * This Wifi configuration is expected for OSU(Online Sign Up) of Passpoint Release 2. + * @hide + */ + public boolean osu; + + /** * @hide * Last time the system was connected to this configuration. */ @@ -1645,6 +1652,7 @@ public class WifiConfiguration implements Parcelable { selfAdded = false; didSelfAdd = false; ephemeral = false; + osu = false; trusted = true; // Networks are considered trusted by default. meteredHint = false; meteredOverride = METERED_OVERRIDE_NONE; @@ -1755,6 +1763,7 @@ public class WifiConfiguration implements Parcelable { if (this.selfAdded) sbuf.append(" selfAdded"); if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess"); if (this.ephemeral) sbuf.append(" ephemeral"); + if (this.osu) sbuf.append(" osu"); if (this.trusted) sbuf.append(" trusted"); if (this.meteredHint) sbuf.append(" meteredHint"); if (this.useExternalScores) sbuf.append(" useExternalScores"); @@ -2244,6 +2253,7 @@ public class WifiConfiguration implements Parcelable { validatedInternetAccess = source.validatedInternetAccess; isLegacyPasspointConfig = source.isLegacyPasspointConfig; ephemeral = source.ephemeral; + osu = source.osu; trusted = source.trusted; meteredHint = source.meteredHint; meteredOverride = source.meteredOverride; @@ -2340,6 +2350,7 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(recentFailure.getAssociationStatus()); dest.writeParcelable(mRandomizedMacAddress, flags); dest.writeInt(macRandomizationSetting); + dest.writeInt(osu ? 1 : 0); } /** Implement the Parcelable interface {@hide} */ @@ -2410,6 +2421,7 @@ public class WifiConfiguration implements Parcelable { config.recentFailure.setAssociationStatus(in.readInt()); config.mRandomizedMacAddress = in.readParcelable(null); config.macRandomizationSetting = in.readInt(); + config.osu = in.readInt() != 0; return config; } diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index e5dcef00f001..7cdd16a6a4ed 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -19,6 +19,7 @@ package android.net.wifi; import android.annotation.UnsupportedAppUsage; import android.net.NetworkInfo.DetailedState; import android.net.NetworkUtils; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -69,7 +70,7 @@ public class WifiInfo implements Parcelable { } private SupplicantState mSupplicantState; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mBSSID; @UnsupportedAppUsage private WifiSsid mWifiSsid; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a7c2ff0f875c..e67e8ea7d9ab 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2017,6 +2017,8 @@ public class WifiManager { public static final int WIFI_FEATURE_OWE = 0x20000000; // Enhanced Open /** @hide */ public static final int WIFI_FEATURE_LOW_LATENCY = 0x40000000; // Low Latency modes + /** @hide */ + public static final int WIFI_FEATURE_DPP = 0x80000000; // DPP (Easy-Connect) private int getSupportedFeatures() { try { @@ -4463,6 +4465,13 @@ public class WifiManager { } /** + * @return true if this device supports Wi-Fi Device Provisioning Protocol (Easy-connect) + */ + public boolean isDppSupported() { + return isFeatureSupported(WIFI_FEATURE_DPP); + } + + /** * Gets the factory Wi-Fi MAC addresses. * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array * if failed. @@ -4541,4 +4550,146 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } + + /* DPP - Device Provisioning Protocol AKA "Easy Connect" */ + + /** + * DPP Network role: Station. + * @hide + */ + @SystemApi + public static final int DPP_NETWORK_ROLE_STA = 0; + + /** + * DPP Network role: Access Point. + * @hide + */ + @SystemApi + public static final int DPP_NETWORK_ROLE_AP = 1; + + /** @hide */ + @IntDef(prefix = {"DPP_NETWORK_ROLE_"}, value = { + DPP_NETWORK_ROLE_STA, + DPP_NETWORK_ROLE_AP, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppNetworkRole {} + + /** + * Start DPP in Configurator-Initiator role. The current device will initiate DPP bootstrapping + * with a peer, and configure the peer with the SSID and password of the specified network using + * the DPP protocol on an encrypted link. + * + * @param enrolleeUri URI of the Enrollee obtained separately (e.g. QR code scanning) + * @param selectedNetworkId Selected network ID to be sent to the peer + * @param enrolleeNetworkRole The network role of the enrollee + * @param callback Callback for status updates + * @param handler The handler on whose thread to execute the callbacks. Null for main thread. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD}) + public void startDppAsConfiguratorInitiator(@NonNull String enrolleeUri, + int selectedNetworkId, @DppNetworkRole int enrolleeNetworkRole, + @Nullable Handler handler, @NonNull DppStatusCallback callback) { + Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper(); + Binder binder = new Binder(); + try { + mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, + enrolleeNetworkRole, new DppCallbackProxy(looper, callback)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Start DPP in Enrollee-Initiator role. The current device will initiate DPP bootstrapping + * with a peer, and receive the SSID and password from the peer configurator. + * + * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning) + * @param callback Callback for status updates + * @param handler The handler on whose thread to execute the callbacks. Null for main thread. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD}) + public void startDppAsEnrolleeInitiator(@NonNull String configuratorUri, + @Nullable Handler handler, @NonNull DppStatusCallback callback) { + Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper(); + Binder binder = new Binder(); + try { + mService.startDppAsEnrolleeInitiator(binder, configuratorUri, + new DppCallbackProxy(looper, callback)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Stop or abort a current DPP session. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD}) + public void stopDppSession() { + try { + /* Request lower layers to stop/abort and clear resources */ + mService.stopDppSession(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Helper class to support DPP callbacks + * @hide + */ + @SystemApi + private static class DppCallbackProxy extends IDppCallback.Stub { + private final Handler mHandler; + private final DppStatusCallback mDppStatusCallback; + + DppCallbackProxy(Looper looper, DppStatusCallback dppStatusCallback) { + mHandler = new Handler(looper); + mDppStatusCallback = dppStatusCallback; + } + + @Override + public void onSuccessConfigReceived(int newNetworkId) { + Log.d(TAG, "DPP onSuccessConfigReceived callback"); + mHandler.post(() -> { + mDppStatusCallback.onEnrolleeSuccess(newNetworkId); + }); + } + + @Override + public void onSuccess(int status) { + Log.d(TAG, "DPP onSuccess callback"); + mHandler.post(() -> { + mDppStatusCallback.onConfiguratorSuccess(status); + }); + } + + @Override + public void onFailure(int status) { + Log.d(TAG, "DPP onFailure callback"); + mHandler.post(() -> { + mDppStatusCallback.onFailure(status); + }); + } + + @Override + public void onProgress(int status) { + Log.d(TAG, "DPP onProgress callback"); + mHandler.post(() -> { + mDppStatusCallback.onProgress(status); + }); + } + } } diff --git a/wifi/java/android/net/wifi/WpsInfo.java b/wifi/java/android/net/wifi/WpsInfo.java index d12cce174192..ae3104bd5567 100644 --- a/wifi/java/android/net/wifi/WpsInfo.java +++ b/wifi/java/android/net/wifi/WpsInfo.java @@ -16,63 +16,42 @@ package android.net.wifi; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; /** * A class representing Wi-Fi Protected Setup - * @deprecated This class is no longer supported. + * * {@see WifiP2pConfig} */ -@Deprecated public class WpsInfo implements Parcelable { - /** Push button configuration - * @deprecated This is no longer supported.*/ - @Deprecated + /** Push button configuration */ public static final int PBC = 0; - /** Display pin method configuration - pin is generated and displayed on device - * @deprecated This is no longer supported.*/ - @Deprecated + /** Display pin method configuration - pin is generated and displayed on device */ public static final int DISPLAY = 1; - /** Keypad pin method configuration - pin is entered on device - * @deprecated This is no longer supported.*/ - @Deprecated + /** Keypad pin method configuration - pin is entered on device */ public static final int KEYPAD = 2; - /** Label pin method configuration - pin is labelled on device - * @deprecated This is no longer supported.*/ - @Deprecated + /** Label pin method configuration - pin is labelled on device */ public static final int LABEL = 3; - /** Invalid configuration - * @deprecated This is no longer supported.*/ - @Deprecated + /** Invalid configuration */ public static final int INVALID = 4; - /** Wi-Fi Protected Setup. www.wi-fi.org/wifi-protected-setup has details - * @deprecated This is no longer supported.*/ - @Deprecated + /** Wi-Fi Protected Setup. www.wi-fi.org/wifi-protected-setup has details */ public int setup; - /** Passed with pin method KEYPAD - * @deprecated This is no longer supported.*/ - @Deprecated + /** Passed with pin method KEYPAD */ public String BSSID; - /** Passed with pin method configuration - * @deprecated This is no longer supported.*/ - @Deprecated + /** Passed with pin method configuration */ public String pin; - /** @deprecated This API is no longer supported.*/ - @Deprecated public WpsInfo() { setup = INVALID; BSSID = null; pin = null; } - /** @deprecated This API is no longer supported.*/ - @Deprecated public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append(" setup: ").append(setup); @@ -84,16 +63,12 @@ public class WpsInfo implements Parcelable { return sbuf.toString(); } - /** Implement the Parcelable interface - * @deprecated This API is no longer supported.*/ - @Deprecated + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /* Copy constructor - * @deprecated This API is no longer supported.*/ - @Deprecated + /* Copy constructor */ public WpsInfo(WpsInfo source) { if (source != null) { setup = source.setup; @@ -102,22 +77,16 @@ public class WpsInfo implements Parcelable { } } - /** Implement the Parcelable interface - * @deprecated This API is no longer supported. */ - @Deprecated + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(setup); dest.writeString(BSSID); dest.writeString(pin); } - /** Implement the Parcelable interface - * @deprecated This API is no longer supported.*/ - @Deprecated + /** Implement the Parcelable interface */ public static final Creator<WpsInfo> CREATOR = new Creator<WpsInfo>() { - /** @deprecated This API is nolonger supported.*/ - @Deprecated public WpsInfo createFromParcel(Parcel in) { WpsInfo config = new WpsInfo(); config.setup = in.readInt(); @@ -126,8 +95,6 @@ public class WpsInfo implements Parcelable { return config; } - /** @deprecated This API is nolonger supported.*/ - @Deprecated public WpsInfo[] newArray(int size) { return new WpsInfo[size]; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index e0442f2fd5ae..068b959f14ca 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -311,12 +311,19 @@ public class WifiP2pManager { "android.net.wifi.p2p.EXTRA_HANDOVER_MESSAGE"; /** - * The lookup key for a calling package returned by the WifiP2pService. + * The lookup key for a calling package name from WifiP2pManager * @hide */ public static final String CALLING_PACKAGE = "android.net.wifi.p2p.CALLING_PACKAGE"; + /** + * The lookup key for a calling package binder from WifiP2pManager + * @hide + */ + public static final String CALLING_BINDER = + "android.net.wifi.p2p.CALLING_BINDER"; + IWifiP2pManager mService; private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER; @@ -536,6 +543,9 @@ public class WifiP2pManager { /** @hide */ public static final int RESPONSE_NETWORK_INFO = BASE + 95; + /** @hide */ + public static final int UPDATE_CHANNEL_INFO = BASE + 96; + /** * Create a new WifiP2pManager instance. Applications use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve @@ -1098,6 +1108,11 @@ public class WifiP2pManager { Channel c = new Channel(srcContext, srcLooper, listener, binder, this); if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger) == AsyncChannel.STATUS_SUCCESSFUL) { + Bundle bundle = new Bundle(); + bundle.putString(CALLING_PACKAGE, c.mContext.getOpPackageName()); + bundle.putBinder(CALLING_BINDER, binder); + c.mAsyncChannel.sendMessage(UPDATE_CHANNEL_INFO, 0, + c.putListener(null), bundle); return c; } else { c.close(); @@ -1124,6 +1139,7 @@ public class WifiP2pManager { * @param c is the channel created at {@link #initialize} * @param listener for callbacks on success or failure. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void discoverPeers(Channel c, ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener)); @@ -1167,6 +1183,7 @@ public class WifiP2pManager { * @param config options as described in {@link WifiP2pConfig} class * @param listener for callbacks on success or failure. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void connect(Channel c, WifiP2pConfig config, ActionListener listener) { checkChannel(c); checkP2pConfig(config); @@ -1208,6 +1225,7 @@ public class WifiP2pManager { * @param c is the channel created at {@link #initialize} * @param listener for callbacks on success or failure. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void createGroup(Channel c, ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.PERSISTENT_NET_ID, @@ -1238,6 +1256,7 @@ public class WifiP2pManager { * @param config the configuration of a p2p group. * @param listener for callbacks on success or failure. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void createGroup(@NonNull Channel c, @Nullable WifiP2pConfig config, @Nullable ActionListener listener) { @@ -1316,6 +1335,7 @@ public class WifiP2pManager { * @param servInfo is a local service information. * @param listener for callbacks on success or failure. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void addLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener) { checkChannel(c); checkServiceInfo(servInfo); @@ -1425,6 +1445,7 @@ public class WifiP2pManager { * @param c is the channel created at {@link #initialize} * @param listener for callbacks on success or failure. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void discoverServices(Channel c, ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, c.putListener(listener)); @@ -1500,12 +1521,10 @@ public class WifiP2pManager { * @param c is the channel created at {@link #initialize} * @param listener for callback when peer list is available. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void requestPeers(Channel c, PeerListListener listener) { checkChannel(c); - Bundle callingPackage = new Bundle(); - callingPackage.putString(CALLING_PACKAGE, c.mContext.getOpPackageName()); - c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener), - callingPackage); + c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener)); } /** @@ -1525,6 +1544,7 @@ public class WifiP2pManager { * @param c is the channel created at {@link #initialize} * @param listener for callback when group info is available. Can be null. */ + @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void requestGroupInfo(Channel c, GroupInfoListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO, 0, c.putListener(listener)); @@ -1697,10 +1717,7 @@ public class WifiP2pManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) { checkChannel(c); - Bundle callingPackage = new Bundle(); - callingPackage.putString(CALLING_PACKAGE, c.mContext.getOpPackageName()); - c.mAsyncChannel.sendMessage(FACTORY_RESET, 0, c.putListener(listener), - callingPackage); + c.mAsyncChannel.sendMessage(FACTORY_RESET, 0, c.putListener(listener)); } /** diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index ef1bff4c793c..f9ef08fa6dc1 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -17,6 +17,7 @@ package android.net.wifi.p2p; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcelable; import android.os.Parcel; @@ -54,7 +55,7 @@ public class WifiP2pWfdInfo implements Parcelable { private int mMaxThroughput; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public WifiP2pWfdInfo() { } diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java index c9e9867e200d..e32c8e80ad1c 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java @@ -18,6 +18,7 @@ package android.net.wifi.p2p.nsd; import android.annotation.UnsupportedAppUsage; import android.net.nsd.DnsSdTxtRecord; +import android.os.Build; import android.text.TextUtils; import java.util.ArrayList; @@ -174,7 +175,7 @@ public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo { * @param version version number * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) static String createRequest(String dnsName, int dnsType, int version) { StringBuffer sb = new StringBuffer(); diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java index 35631985bdfc..e9ee7bbcaf6c 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java @@ -17,6 +17,7 @@ package android.net.wifi.p2p.nsd; import android.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -84,7 +85,7 @@ public class WifiP2pServiceInfo implements Parcelable { * {"upnp", "10", "uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp * -org:service:ContentDirectory:2"} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private List<String> mQueryList; /** @@ -93,7 +94,7 @@ public class WifiP2pServiceInfo implements Parcelable { * @param queryList query string for wpa_supplicant * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) protected WifiP2pServiceInfo(List<String> queryList) { if (queryList == null) { throw new IllegalArgumentException("query list cannot be null"); diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java index 2e7f44802ab2..f1f2262b0ec4 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java @@ -18,6 +18,7 @@ package android.net.wifi.p2p.nsd; import android.annotation.UnsupportedAppUsage; import android.net.wifi.p2p.WifiP2pManager; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -73,7 +74,7 @@ public class WifiP2pServiceRequest implements Parcelable { * @param query The part of service specific query. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) protected WifiP2pServiceRequest(int protocolType, String query) { validateQuery(query); |