diff options
217 files changed, 3887 insertions, 2267 deletions
diff --git a/apct-tests/perftests/core/AndroidTest.xml b/apct-tests/perftests/core/AndroidTest.xml index 6aa34a627940..1b289130124f 100644 --- a/apct-tests/perftests/core/AndroidTest.xml +++ b/apct-tests/perftests/core/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.perftests.core" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/apct-tests/perftests/multiuser/AndroidTest.xml b/apct-tests/perftests/multiuser/AndroidTest.xml index 6ede8275afcb..512dbc9a8de7 100644 --- a/apct-tests/perftests/multiuser/AndroidTest.xml +++ b/apct-tests/perftests/multiuser/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.perftests.multiuser" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/api/current.txt b/api/current.txt index c351beee7072..53ffb77899e6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5393,7 +5393,7 @@ package android.app { method public android.app.Notification.Builder addAction(android.app.Notification.Action); method public android.app.Notification.Builder addExtras(android.os.Bundle); method public deprecated android.app.Notification.Builder addPerson(java.lang.String); - method public android.app.Notification.Builder addPerson(android.app.Notification.Person); + method public android.app.Notification.Builder addPerson(android.app.Person); method public android.app.Notification build(); method public android.widget.RemoteViews createBigContentView(); method public android.widget.RemoteViews createContentView(); @@ -5518,15 +5518,15 @@ package android.app { public static class Notification.MessagingStyle extends android.app.Notification.Style { ctor public deprecated Notification.MessagingStyle(java.lang.CharSequence); - ctor public Notification.MessagingStyle(android.app.Notification.Person); + ctor public Notification.MessagingStyle(android.app.Person); method public android.app.Notification.MessagingStyle addHistoricMessage(android.app.Notification.MessagingStyle.Message); method public deprecated android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence); - method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, android.app.Notification.Person); + method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, android.app.Person); method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message); method public java.lang.CharSequence getConversationTitle(); method public java.util.List<android.app.Notification.MessagingStyle.Message> getHistoricMessages(); method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages(); - method public android.app.Notification.Person getUser(); + method public android.app.Person getUser(); method public deprecated java.lang.CharSequence getUserDisplayName(); method public boolean isGroupConversation(); method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence); @@ -5536,37 +5536,17 @@ package android.app { public static final class Notification.MessagingStyle.Message { ctor public deprecated Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence); - ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, android.app.Notification.Person); + ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, android.app.Person); method public java.lang.String getDataMimeType(); method public android.net.Uri getDataUri(); method public android.os.Bundle getExtras(); method public deprecated java.lang.CharSequence getSender(); - method public android.app.Notification.Person getSenderPerson(); + method public android.app.Person getSenderPerson(); method public java.lang.CharSequence getText(); method public long getTimestamp(); method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri); } - public static final class Notification.Person implements android.os.Parcelable { - ctor protected Notification.Person(android.os.Parcel); - ctor public Notification.Person(); - method public int describeContents(); - method public android.graphics.drawable.Icon getIcon(); - method public java.lang.String getKey(); - method public java.lang.CharSequence getName(); - method public java.lang.String getUri(); - method public boolean isBot(); - method public boolean isImportant(); - method public android.app.Notification.Person setBot(boolean); - method public android.app.Notification.Person setIcon(android.graphics.drawable.Icon); - method public android.app.Notification.Person setImportant(boolean); - method public android.app.Notification.Person setKey(java.lang.String); - method public android.app.Notification.Person setName(java.lang.CharSequence); - method public android.app.Notification.Person setUri(java.lang.String); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.app.Notification.Person> CREATOR; - } - public static abstract class Notification.Style { ctor public Notification.Style(); method public android.app.Notification build(); @@ -5817,6 +5797,30 @@ package android.app { method public abstract void onSendFinished(android.app.PendingIntent, android.content.Intent, int, java.lang.String, android.os.Bundle); } + public final class Person implements android.os.Parcelable { + method public int describeContents(); + method public android.graphics.drawable.Icon getIcon(); + method public java.lang.String getKey(); + method public java.lang.CharSequence getName(); + method public java.lang.String getUri(); + method public boolean isBot(); + method public boolean isImportant(); + method public android.app.Person.Builder toBuilder(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.Person> CREATOR; + } + + public static class Person.Builder { + ctor public Person.Builder(); + method public android.app.Person build(); + method public android.app.Person.Builder setBot(boolean); + method public android.app.Person.Builder setIcon(android.graphics.drawable.Icon); + method public android.app.Person.Builder setImportant(boolean); + method public android.app.Person.Builder setKey(java.lang.String); + method public android.app.Person.Builder setName(java.lang.CharSequence); + method public android.app.Person.Builder setUri(java.lang.String); + } + public final class PictureInPictureParams implements android.os.Parcelable { method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); @@ -6749,6 +6753,12 @@ package android.app.admin { field public static final android.os.Parcelable.Creator<android.app.admin.DnsEvent> CREATOR; } + public class FreezePeriod { + ctor public FreezePeriod(java.time.MonthDay, java.time.MonthDay); + method public java.time.MonthDay getEnd(); + method public java.time.MonthDay getStart(); + } + public abstract class NetworkEvent implements android.os.Parcelable { method public int describeContents(); method public long getId(); @@ -6819,16 +6829,16 @@ package android.app.admin { field public static final int SECURITY_PATCH_STATE_UNKNOWN = 0; // 0x0 } - public class SystemUpdatePolicy implements android.os.Parcelable { + public final class SystemUpdatePolicy implements android.os.Parcelable { method public static android.app.admin.SystemUpdatePolicy createAutomaticInstallPolicy(); method public static android.app.admin.SystemUpdatePolicy createPostponeInstallPolicy(); method public static android.app.admin.SystemUpdatePolicy createWindowedInstallPolicy(int, int); method public int describeContents(); - method public java.util.List<android.util.Pair<java.lang.Integer, java.lang.Integer>> getFreezePeriods(); + method public java.util.List<android.app.admin.FreezePeriod> getFreezePeriods(); method public int getInstallWindowEnd(); method public int getInstallWindowStart(); method public int getPolicyType(); - method public android.app.admin.SystemUpdatePolicy setFreezePeriods(java.util.List<android.util.Pair<java.lang.Integer, java.lang.Integer>>); + method public android.app.admin.SystemUpdatePolicy setFreezePeriods(java.util.List<android.app.admin.FreezePeriod>); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdatePolicy> CREATOR; field public static final int TYPE_INSTALL_AUTOMATIC = 1; // 0x1 @@ -6841,11 +6851,12 @@ package android.app.admin { method public int getErrorCode(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdatePolicy.ValidationFailedException> CREATOR; - field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 5; // 0x5 - field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 4; // 0x4 - field public static final int ERROR_DUPLICATE_OR_OVERLAP = 1; // 0x1 - field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 3; // 0x3 - field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 2; // 0x2 + field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 6; // 0x6 + field public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 5; // 0x5 + field public static final int ERROR_DUPLICATE_OR_OVERLAP = 2; // 0x2 + field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 4; // 0x4 + field public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 3; // 0x3 + field public static final int ERROR_UNKNOWN = 1; // 0x1 } } @@ -44689,7 +44700,7 @@ package android.text.util { method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); field public static final int ALL = 15; // 0xf field public static final int EMAIL_ADDRESSES = 2; // 0x2 - field public static final int MAP_ADDRESSES = 8; // 0x8 + field public static final deprecated int MAP_ADDRESSES = 8; // 0x8 field public static final int PHONE_NUMBERS = 4; // 0x4 field public static final int WEB_URLS = 1; // 0x1 field public static final android.text.util.Linkify.MatchFilter sPhoneNumberMatchFilter; @@ -47880,7 +47891,7 @@ package android.view { method public void setVerticalScrollBarEnabled(boolean); method public void setVerticalScrollbarPosition(int); method public void setVisibility(int); - method public void setWillNotCacheDrawing(boolean); + method public deprecated void setWillNotCacheDrawing(boolean); method public void setWillNotDraw(boolean); method public void setX(float); method public void setY(float); @@ -47898,7 +47909,7 @@ package android.view { method public void unscheduleDrawable(android.graphics.drawable.Drawable); method public final void updateDragShadow(android.view.View.DragShadowBuilder); method protected boolean verifyDrawable(android.graphics.drawable.Drawable); - method public boolean willNotCacheDrawing(); + method public deprecated boolean willNotCacheDrawing(); method public boolean willNotDraw(); field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2 field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0 @@ -51308,7 +51319,7 @@ package android.webkit { method public void documentHasImages(android.os.Message); method public static void enableSlowWholeDocumentDraw(); method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>); - method public static java.lang.String findAddress(java.lang.String); + method public static deprecated java.lang.String findAddress(java.lang.String); method public deprecated int findAll(java.lang.String); method public void findAllAsync(java.lang.String); method public void findNext(boolean); @@ -51320,7 +51331,6 @@ package android.webkit { method public android.graphics.Bitmap getFavicon(); method public android.webkit.WebView.HitTestResult getHitTestResult(); method public deprecated java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String); - method public android.os.Looper getLooper(); method public java.lang.String getOriginalUrl(); method public int getProgress(); method public boolean getRendererPriorityWaivedWhenNotVisible(); diff --git a/api/system-current.txt b/api/system-current.txt index 656001c1fcc6..76a71cd7c44e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -317,6 +317,7 @@ package android.app { public class BroadcastOptions { method public static android.app.BroadcastOptions makeBasic(); + method public void setDontSendToRestrictedApps(boolean); method public void setTemporaryAppWhitelistDuration(long); method public android.os.Bundle toBundle(); } @@ -452,7 +453,7 @@ package android.app.admin { field public static final int STATE_USER_UNMANAGED = 0; // 0x0 } - public class SystemUpdatePolicy implements android.os.Parcelable { + public final class SystemUpdatePolicy implements android.os.Parcelable { method public int describeContents(); method public android.app.admin.SystemUpdatePolicy.InstallationOption getInstallationOptionAt(long); method public void writeToParcel(android.os.Parcel, int); @@ -4355,6 +4356,7 @@ package android.security.keystore.recovery { method public byte[] getServerParams(); method public int getSnapshotVersion(); method public java.security.cert.CertPath getTrustedHardwareCertPath(); + method public deprecated byte[] getTrustedHardwarePublicKey(); method public java.util.List<android.security.keystore.recovery.WrappedApplicationKey> getWrappedApplicationKeys(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.security.keystore.recovery.KeyChainSnapshot> CREATOR; @@ -4379,18 +4381,25 @@ package android.security.keystore.recovery { public class RecoveryController { method public android.security.keystore.recovery.RecoverySession createRecoverySession(); + method public byte[] generateAndStoreKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException; + method public deprecated java.security.Key generateKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException; method public java.security.Key generateKey(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException; + method public deprecated java.util.List<java.lang.String> getAliases(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public java.util.List<java.lang.String> getAliases() throws android.security.keystore.recovery.InternalRecoveryServiceException; method public static android.security.keystore.recovery.RecoveryController getInstance(android.content.Context); method public java.security.Key getKey(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException, java.security.UnrecoverableKeyException; method public android.security.keystore.recovery.KeyChainSnapshot getKeyChainSnapshot() throws android.security.keystore.recovery.InternalRecoveryServiceException; + method public deprecated android.security.keystore.recovery.KeyChainSnapshot getRecoveryData() throws android.security.keystore.recovery.InternalRecoveryServiceException; method public int[] getRecoverySecretTypes() throws android.security.keystore.recovery.InternalRecoveryServiceException; + method public deprecated int getRecoveryStatus(java.lang.String, java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public int getRecoveryStatus(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public java.util.Map<java.lang.String, java.security.cert.X509Certificate> getRootCertificates(); method public java.security.Key importKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException; + method public deprecated void initRecoveryService(java.lang.String, byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; method public void initRecoveryService(java.lang.String, byte[], byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; method public void removeKey(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public void setRecoverySecretTypes(int[]) throws android.security.keystore.recovery.InternalRecoveryServiceException; + method public deprecated void setRecoveryStatus(java.lang.String, java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.content.pm.PackageManager.NameNotFoundException; method public void setRecoveryStatus(java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public void setServerParams(byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public void setSnapshotCreatedPendingIntent(android.app.PendingIntent) throws android.security.keystore.recovery.InternalRecoveryServiceException; @@ -4402,6 +4411,9 @@ package android.security.keystore.recovery { public class RecoverySession implements java.lang.AutoCloseable { method public void close(); method public java.util.Map<java.lang.String, java.security.Key> recoverKeyChainSnapshot(byte[], java.util.List<android.security.keystore.recovery.WrappedApplicationKey>) throws android.security.keystore.recovery.DecryptionFailedException, android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.SessionExpiredException; + method public deprecated java.util.Map<java.lang.String, byte[]> recoverKeys(byte[], java.util.List<android.security.keystore.recovery.WrappedApplicationKey>) throws android.security.keystore.recovery.DecryptionFailedException, android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.SessionExpiredException; + method public deprecated byte[] start(byte[], byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; + method public deprecated byte[] start(java.security.cert.CertPath, byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; method public byte[] start(java.lang.String, java.security.cert.CertPath, byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; } @@ -4411,6 +4423,7 @@ package android.security.keystore.recovery { public final class WrappedApplicationKey implements android.os.Parcelable { method public int describeContents(); + method public deprecated byte[] getAccount(); method public java.lang.String getAlias(); method public byte[] getEncryptedKeyMaterial(); method public void writeToParcel(android.os.Parcel, int); @@ -4420,6 +4433,7 @@ package android.security.keystore.recovery { public static class WrappedApplicationKey.Builder { ctor public WrappedApplicationKey.Builder(); method public android.security.keystore.recovery.WrappedApplicationKey build(); + method public deprecated android.security.keystore.recovery.WrappedApplicationKey.Builder setAccount(byte[]); method public android.security.keystore.recovery.WrappedApplicationKey.Builder setAlias(java.lang.String); method public android.security.keystore.recovery.WrappedApplicationKey.Builder setEncryptedKeyMaterial(byte[]); } @@ -5108,6 +5122,7 @@ package android.telephony { } public abstract class NetworkService extends android.app.Service { + ctor public NetworkService(); method protected abstract android.telephony.NetworkService.NetworkServiceProvider createNetworkServiceProvider(int); field public static final java.lang.String NETWORK_SERVICE_EXTRA_SLOT_ID = "android.telephony.extra.SLOT_ID"; field public static final java.lang.String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService"; @@ -5389,6 +5404,7 @@ package android.telephony.data { } public abstract class DataService extends android.app.Service { + ctor public DataService(); method public abstract android.telephony.data.DataService.DataServiceProvider createDataServiceProvider(int); field public static final java.lang.String DATA_SERVICE_EXTRA_SLOT_ID = "android.telephony.data.extra.SLOT_ID"; field public static final java.lang.String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService"; diff --git a/api/system-removed.txt b/api/system-removed.txt index 7cf12ef3c595..48f43e0880da 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -91,37 +91,6 @@ package android.os { } -package android.security.keystore.recovery { - - public final class KeyChainSnapshot implements android.os.Parcelable { - method public deprecated byte[] getTrustedHardwarePublicKey(); - } - - public class RecoveryController { - method public deprecated java.security.Key generateKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException; - method public deprecated java.util.List<java.lang.String> getAliases(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException; - method public deprecated android.security.keystore.recovery.KeyChainSnapshot getRecoveryData() throws android.security.keystore.recovery.InternalRecoveryServiceException; - method public deprecated int getRecoveryStatus(java.lang.String, java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException; - method public deprecated void initRecoveryService(java.lang.String, byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; - method public deprecated void setRecoveryStatus(java.lang.String, java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.content.pm.PackageManager.NameNotFoundException; - } - - public class RecoverySession implements java.lang.AutoCloseable { - method public deprecated java.util.Map<java.lang.String, byte[]> recoverKeys(byte[], java.util.List<android.security.keystore.recovery.WrappedApplicationKey>) throws android.security.keystore.recovery.DecryptionFailedException, android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.SessionExpiredException; - method public deprecated byte[] start(byte[], byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; - method public deprecated byte[] start(java.security.cert.CertPath, byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; - } - - public final class WrappedApplicationKey implements android.os.Parcelable { - method public deprecated byte[] getAccount(); - } - - public static class WrappedApplicationKey.Builder { - method public deprecated android.security.keystore.recovery.WrappedApplicationKey.Builder setAccount(byte[]); - } - -} - package android.service.notification { public abstract class NotificationListenerService extends android.app.Service { diff --git a/api/test-current.txt b/api/test-current.txt index 48786909d4b3..23b68199f9ca 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -467,12 +467,49 @@ package android.location { } +package android.media { + + public final class AudioFormat implements android.os.Parcelable { + method public static int channelCountFromInChannelMask(int); + method public static int channelCountFromOutChannelMask(int); + method public static int getBytesPerSample(int); + method public static boolean isEncodingLinearPcm(int); + } + + public static final class VolumeShaper.Configuration.Builder { + method public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int); + } + +} + package android.media.audiofx { public class AudioEffect { + method public static int byteArrayToInt(byte[]); + method public static short byteArrayToShort(byte[]); + method public int getParameter(byte[], byte[]) throws java.lang.IllegalStateException; + method public int getParameter(int, byte[]) throws java.lang.IllegalStateException; + method public int getParameter(int, int[]) throws java.lang.IllegalStateException; + method public int getParameter(int, short[]) throws java.lang.IllegalStateException; + method public int getParameter(int[], short[]) throws java.lang.IllegalStateException; + method public static byte[] intToByteArray(int); + method public static boolean isEffectTypeAvailable(java.util.UUID); + method public static boolean isError(int); + method public int setParameter(byte[], byte[]) throws java.lang.IllegalStateException; + method public int setParameter(int, int) throws java.lang.IllegalStateException; + method public int setParameter(int, short) throws java.lang.IllegalStateException; + method public int setParameter(int, byte[]) throws java.lang.IllegalStateException; + method public int setParameter(int[], int[]) throws java.lang.IllegalStateException; + method public int setParameter(int[], byte[]) throws java.lang.IllegalStateException; + method public void setParameterListener(android.media.audiofx.AudioEffect.OnParameterChangeListener); + method public static byte[] shortToByteArray(short); field public static final java.util.UUID EFFECT_TYPE_NULL; } + public static abstract interface AudioEffect.OnParameterChangeListener { + method public abstract void onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]); + } + } package android.net { @@ -786,6 +823,10 @@ package android.telephony { public class ServiceState implements android.os.Parcelable { method public void setCdmaSystemAndNetworkId(int, int); + method public void setCellBandwidths(int[]); + method public void setChannelNumber(int); + method public void setRilDataRadioTechnology(int); + method public void setRilVoiceRadioTechnology(int); } public class TelephonyManager { diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 41527f693923..90ce73576e90 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -212,7 +212,10 @@ void StatsLogProcessor::OnConfigUpdatedLocked( sp<MetricsManager> newMetricsManager = new MetricsManager(key, config, mTimeBaseSec, (timestampNs - 1) / NS_PER_SEC + 1, mUidMap, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor); - + auto it = mMetricsManagers.find(key); + if (it != mMetricsManagers.end()) { + WriteDataToDiskLocked(it->first); + } if (newMetricsManager->isConfigValid()) { mUidMap->OnConfigUpdated(key); if (newMetricsManager->shouldAddUidMapListener()) { @@ -251,19 +254,10 @@ void StatsLogProcessor::dumpStates(FILE* out, bool verbose) { * onDumpReport dumps serialized ConfigMetricsReportList into outData. */ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs, + const bool include_current_partial_bucket, vector<uint8_t>* outData) { std::lock_guard<std::mutex> lock(mMetricsMutex); - auto it = mMetricsManagers.find(key); - if (it == mMetricsManagers.end()) { - ALOGW("Config source %s does not exist", key.ToString().c_str()); - return; - } - - // This allows another broadcast to be sent within the rate-limit period if we get close to - // filling the buffer again soon. - mLastBroadcastTimes.erase(key); - ProtoOutputStream proto; // Start of ConfigKey. @@ -273,18 +267,26 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim proto.end(configKeyToken); // End of ConfigKey. - // Start of ConfigMetricsReport (reports). - uint64_t reportsToken = - proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS); - onConfigMetricsReportLocked(key, dumpTimeStampNs, &proto); - proto.end(reportsToken); - // End of ConfigMetricsReport (reports). - - // Then, check stats-data directory to see there's any file containing // ConfigMetricsReport from previous shutdowns to concatenate to reports. StorageManager::appendConfigMetricsReport(key, &proto); + auto it = mMetricsManagers.find(key); + if (it != mMetricsManagers.end()) { + // This allows another broadcast to be sent within the rate-limit period if we get close to + // filling the buffer again soon. + mLastBroadcastTimes.erase(key); + + // Start of ConfigMetricsReport (reports). + uint64_t reportsToken = + proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS); + onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket, &proto); + proto.end(reportsToken); + // End of ConfigMetricsReport (reports). + } else { + ALOGW("Config source %s does not exist", key.ToString().c_str()); + } + if (outData != nullptr) { outData->clear(); outData->resize(proto.size()); @@ -298,7 +300,7 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim } } - StatsdStats::getInstance().noteMetricsReportSent(key); + StatsdStats::getInstance().noteMetricsReportSent(key, proto.size()); } /* @@ -306,16 +308,20 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim */ void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, + const bool include_current_partial_bucket, ProtoOutputStream* proto) { // We already checked whether key exists in mMetricsManagers in // WriteDataToDisk. auto it = mMetricsManagers.find(key); + if (it == mMetricsManagers.end()) { + return; + } int64_t lastReportTimeNs = it->second->getLastReportTimeNs(); int64_t lastReportWallClockNs = it->second->getLastReportWallClockNs(); // First, fill in ConfigMetricsReport using current data on memory, which // starts from filling in StatsLogReport's. - it->second->onDumpReport(dumpTimeStampNs, proto); + it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, proto); // Fill in UidMap. uint64_t uidMapToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP); @@ -331,7 +337,6 @@ void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, (long long)lastReportWallClockNs); proto->write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS, (long long)getWallClockNs()); - } void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) { @@ -361,6 +366,7 @@ void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) { std::lock_guard<std::mutex> lock(mMetricsMutex); auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { + WriteDataToDiskLocked(key); mMetricsManagers.erase(it); mUidMap->OnConfigRemoved(key); } @@ -406,24 +412,32 @@ void StatsLogProcessor::flushIfNecessaryLocked( } } -void StatsLogProcessor::WriteDataToDisk() { - std::lock_guard<std::mutex> lock(mMetricsMutex); +void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key) { + ProtoOutputStream proto; + onConfigMetricsReportLocked(key, getElapsedRealtimeNs(), + true /* include_current_partial_bucket*/, &proto); + string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, + (long)getWallClockSec(), key.GetUid(), (long long)key.GetId()); + android::base::unique_fd fd(open(file_name.c_str(), + O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)); + if (fd == -1) { + ALOGE("Attempt to write %s but failed", file_name.c_str()); + return; + } + proto.flush(fd.get()); +} + +void StatsLogProcessor::WriteDataToDiskLocked() { for (auto& pair : mMetricsManagers) { - const ConfigKey& key = pair.first; - ProtoOutputStream proto; - onConfigMetricsReportLocked(key, getElapsedRealtimeNs(), &proto); - string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, - (long)getWallClockSec(), key.GetUid(), (long long)key.GetId()); - android::base::unique_fd fd(open(file_name.c_str(), - O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)); - if (fd == -1) { - VLOG("Attempt to write %s but failed", file_name.c_str()); - return; - } - proto.flush(fd.get()); + WriteDataToDiskLocked(pair.first); } } +void StatsLogProcessor::WriteDataToDisk() { + std::lock_guard<std::mutex> lock(mMetricsMutex); + WriteDataToDiskLocked(); +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index d37429e9ba96..1e82b1e48ebf 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -48,7 +48,8 @@ public: size_t GetMetricsSize(const ConfigKey& key) const; - void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs, vector<uint8_t>* outData); + void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs, + const bool include_current_partial_bucket, vector<uint8_t>* outData); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void onAnomalyAlarmFired( @@ -102,7 +103,11 @@ private: void OnConfigUpdatedLocked( const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config); + void WriteDataToDiskLocked(); + void WriteDataToDiskLocked(const ConfigKey& key); + void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, + const bool include_current_partial_bucket, util::ProtoOutputStream* proto); /* Check if we should send a broadcast if approaching memory limits and if we're over, we diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index dac73ef8cb01..d3cda63e2f86 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -178,23 +178,34 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) { } bool verbose = false; + bool proto = false; if (args.size() > 0 && !args[0].compare(String16("-v"))) { verbose = true; } + if (args.size() > 0 && !args[args.size()-1].compare(String16("--proto"))) { + proto = true; + } - // TODO: Proto format for incident reports - dump_impl(out, verbose); + dump_impl(out, verbose, proto); fclose(out); return NO_ERROR; } /** - * Write debugging data about statsd in text format. + * Write debugging data about statsd in text or proto format. */ -void StatsService::dump_impl(FILE* out, bool verbose) { - StatsdStats::getInstance().dumpStats(out); - mProcessor->dumpStates(out, verbose); +void StatsService::dump_impl(FILE* out, bool verbose, bool proto) { + if (proto) { + vector<uint8_t> data; + StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats. + for (size_t i = 0; i < data.size(); i ++) { + fprintf(out, "%c", data[i]); + } + } else { + StatsdStats::getInstance().dumpStats(out); + mProcessor->dumpStates(out, verbose); + } } /** @@ -325,6 +336,7 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats print-stats\n"); fprintf(out, " Prints some basic stats.\n"); + fprintf(out, " --proto Print proto binary instead of string format.\n"); fprintf(out, "\n"); fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats clear-puller-cache\n"); @@ -501,7 +513,7 @@ status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String if (good) { vector<uint8_t> data; mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(), - &data); + false /* include_current_bucket*/, &data); // TODO: print the returned StatsLogReport to file instead of printing to logcat. if (proto) { for (size_t i = 0; i < data.size(); i ++) { @@ -524,13 +536,28 @@ status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String } status_t StatsService::cmd_print_stats(FILE* out, const Vector<String8>& args) { - vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys(); - for (const ConfigKey& key : configs) { - fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(), - mProcessor->GetMetricsSize(key)); + int argCount = args.size(); + bool proto = false; + if (!std::strcmp("--proto", args[argCount-1].c_str())) { + proto = true; + argCount -= 1; } StatsdStats& statsdStats = StatsdStats::getInstance(); - statsdStats.dumpStats(out); + if (proto) { + vector<uint8_t> data; + statsdStats.dumpStats(&data, false); // does not reset statsdStats. + for (size_t i = 0; i < data.size(); i ++) { + fprintf(out, "%c", data[i]); + } + + } else { + vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys(); + for (const ConfigKey& key : configs) { + fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(), + mProcessor->GetMetricsSize(key)); + } + statsdStats.dumpStats(out); + } return NO_ERROR; } @@ -800,7 +827,8 @@ Status StatsService::getData(int64_t key, vector<uint8_t>* output) { VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); if (checkCallingPermission(String16(kPermissionDump))) { ConfigKey configKey(ipc->getCallingUid(), key); - mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), output); + mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), + false /* include_current_bucket*/, output); return Status::ok(); } else { return Status::fromExceptionCode(binder::Status::EX_SECURITY); diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index a4552e14f205..648e9c59ce0a 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -149,9 +149,9 @@ private: uint32_t serial); /** - * Text output of dumpsys. + * Text or proto output of dumpsys. */ - void dump_impl(FILE* out, bool verbose); + void dump_impl(FILE* out, bool verbose, bool proto); /** * Print usage information for the commands diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index 7b2881da9250..b589d0dc70be 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -76,7 +76,8 @@ const int FIELD_ID_CONFIG_STATS_ALERT_COUNT = 8; const int FIELD_ID_CONFIG_STATS_VALID = 9; const int FIELD_ID_CONFIG_STATS_BROADCAST = 10; const int FIELD_ID_CONFIG_STATS_DATA_DROP = 11; -const int FIELD_ID_CONFIG_STATS_DUMP_REPORT = 12; +const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME = 12; +const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES = 20; const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13; const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14; const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15; @@ -215,21 +216,22 @@ void StatsdStats::noteDataDropped(const ConfigKey& key, int32_t timeSec) { it->second->data_drop_time_sec.push_back(timeSec); } -void StatsdStats::noteMetricsReportSent(const ConfigKey& key) { - noteMetricsReportSent(key, getWallClockSec()); +void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes) { + noteMetricsReportSent(key, num_bytes, getWallClockSec()); } -void StatsdStats::noteMetricsReportSent(const ConfigKey& key, int32_t timeSec) { +void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, + int32_t timeSec) { lock_guard<std::mutex> lock(mLock); auto it = mConfigStats.find(key); if (it == mConfigStats.end()) { ALOGE("Config key %s not found!", key.ToString().c_str()); return; } - if (it->second->dump_report_time_sec.size() == kMaxTimestampCount) { - it->second->dump_report_time_sec.pop_front(); + if (it->second->dump_report_stats.size() == kMaxTimestampCount) { + it->second->dump_report_stats.pop_front(); } - it->second->dump_report_time_sec.push_back(timeSec); + it->second->dump_report_stats.push_back(std::make_pair(timeSec, num_bytes)); } void StatsdStats::noteUidMapDropped(int deltas) { @@ -383,7 +385,7 @@ void StatsdStats::resetInternalLocked() { for (auto& config : mConfigStats) { config.second->broadcast_sent_time_sec.clear(); config.second->data_drop_time_sec.clear(); - config.second->dump_report_time_sec.clear(); + config.second->dump_report_stats.clear(); config.second->annotations.clear(); config.second->matcher_stats.clear(); config.second->condition_stats.clear(); @@ -442,8 +444,8 @@ void StatsdStats::dumpStats(FILE* out) const { fprintf(out, "\tdata drop time: %d\n", dataDropTime); } - for (const auto& dumpTime : configStats->dump_report_time_sec) { - fprintf(out, "\tdump report time: %d\n", dumpTime); + for (const auto& dump : configStats->dump_report_stats) { + fprintf(out, "\tdump report time: %d bytes: %lld\n", dump.first, (long long)dump.second); } for (const auto& stats : pair.second->matcher_stats) { @@ -536,9 +538,16 @@ void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* pr drop); } - for (const auto& dump : configStats.dump_report_time_sec) { - proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT | FIELD_COUNT_REPEATED, - dump); + for (const auto& dump : configStats.dump_report_stats) { + proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME | + FIELD_COUNT_REPEATED, + dump.first); + } + + for (const auto& dump : configStats.dump_report_stats) { + proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES | + FIELD_COUNT_REPEATED, + (long long)dump.second); } for (const auto& annotation : configStats.annotations) { diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 914d2afce7e0..123a703f64a9 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -43,7 +43,7 @@ struct ConfigStats { std::list<int32_t> broadcast_sent_time_sec; std::list<int32_t> data_drop_time_sec; - std::list<int32_t> dump_report_time_sec; + std::list<std::pair<int32_t, int64_t>> dump_report_stats; // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount. std::map<const int64_t, int> matcher_stats; @@ -177,7 +177,7 @@ public: * * The report may be requested via StatsManager API, or through adb cmd. */ - void noteMetricsReportSent(const ConfigKey& key); + void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes); /** * Report the size of output tuple of a condition. @@ -355,7 +355,7 @@ private: void noteDataDropped(const ConfigKey& key, int32_t timeSec); - void noteMetricsReportSent(const ConfigKey& key, int32_t timeSec); + void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, int32_t timeSec); void noteBroadcastSent(const ConfigKey& key, int32_t timeSec); diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp index 98963bdb03b0..c77e07b7698c 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.cpp +++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp @@ -123,8 +123,13 @@ void CountMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition } void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, ProtoOutputStream* protoOutput) { - flushIfNeededLocked(dumpTimeNs); + if (include_current_partial_bucket) { + flushLocked(dumpTimeNs); + } else { + flushIfNeededLocked(dumpTimeNs); + } if (mPastBuckets.empty()) { return; } diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h index 5991c28f910a..cafc882308d4 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.h +++ b/cmds/statsd/src/metrics/CountMetricProducer.h @@ -54,7 +54,9 @@ protected: const LogEvent& event) override; private: + void onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, android::util::ProtoOutputStream* protoOutput) override; // Internal interface to handle condition change. diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp index 19155ded39bf..3125fa7bb63b 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -439,8 +439,13 @@ void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) { } void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, ProtoOutputStream* protoOutput) { - flushIfNeededLocked(dumpTimeNs); + if (include_current_partial_bucket) { + flushLocked(dumpTimeNs); + } else { + flushIfNeededLocked(dumpTimeNs); + } if (mPastBuckets.empty()) { VLOG(" Duration metric, empty return"); return; diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h index 80fb829ae0ff..80fbdde2df09 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.h +++ b/cmds/statsd/src/metrics/DurationMetricProducer.h @@ -62,6 +62,7 @@ private: bool condition, const LogEvent& event); void onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, android::util::ProtoOutputStream* protoOutput) override; // Internal interface to handle condition change. diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp index d55cb3f9ef6c..33ab9aa9b184 100644 --- a/cmds/statsd/src/metrics/EventMetricProducer.cpp +++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp @@ -101,6 +101,7 @@ std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& pr } void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, ProtoOutputStream* protoOutput) { if (mProto->size() <= 0) { return; diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h index fbbc7e2e8598..5c2917400b10 100644 --- a/cmds/statsd/src/metrics/EventMetricProducer.h +++ b/cmds/statsd/src/metrics/EventMetricProducer.h @@ -47,6 +47,7 @@ private: const LogEvent& event) override; void onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, android::util::ProtoOutputStream* protoOutput) override; // Internal interface to handle condition change. diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index 2561d1df970a..3c77aaecfd72 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -156,8 +156,14 @@ void GaugeMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const { } void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, ProtoOutputStream* protoOutput) { VLOG("Gauge metric %lld report now...", (long long)mMetricId); + if (include_current_partial_bucket) { + flushLocked(dumpTimeNs); + } else { + flushIfNeededLocked(dumpTimeNs); + } flushIfNeededLocked(dumpTimeNs); if (mPastBuckets.empty()) { diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h index f49180f3c51f..04b7df96a41f 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.h +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h @@ -88,6 +88,7 @@ protected: private: void onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, android::util::ProtoOutputStream* protoOutput) override; // for testing diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index db5d32cfc1cf..f931e573eb98 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -112,9 +112,11 @@ public: // Output the metrics data to [protoOutput]. All metrics reports end with the same timestamp. // This method clears all the past buckets. - void onDumpReport(const int64_t dumpTimeNs, android::util::ProtoOutputStream* protoOutput) { + void onDumpReport(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, + android::util::ProtoOutputStream* protoOutput) { std::lock_guard<std::mutex> lock(mMutex); - return onDumpReportLocked(dumpTimeNs, protoOutput); + return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, protoOutput); } void dumpStates(FILE* out, bool verbose) const { @@ -168,16 +170,26 @@ protected: virtual void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) = 0; virtual void onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, android::util::ProtoOutputStream* protoOutput) = 0; virtual size_t byteSizeLocked() const = 0; virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0; /** - * Flushes the current bucket if the eventTime is after the current bucket's end time. + * Flushes the current bucket if the eventTime is after the current bucket's end time. This will + also flush the current partial bucket in memory. */ virtual void flushIfNeededLocked(const int64_t& eventTime){}; /** + * Flushes all the data including the current partial bucket. + */ + virtual void flushLocked(const int64_t& eventTime) { + flushIfNeededLocked(eventTime); + flushCurrentBucketLocked(eventTime); + }; + + /** * For metrics that aggregate (ie, every metric producer except for EventMetricProducer), * we need to be able to flush the current buckets on demand (ie, end the current bucket and * start new bucket). If this function is called when eventTimeNs is greater than the current diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 22827b08df52..b7f1bd530d5e 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -190,14 +190,16 @@ void MetricsManager::dropData(const int64_t dropTimeNs) { } } -void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs, ProtoOutputStream* protoOutput) { +void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs, + const bool include_current_partial_bucket, + ProtoOutputStream* protoOutput) { VLOG("=========================Metric Reports Start=========================="); // one StatsLogReport per MetricProduer for (const auto& producer : mAllMetricProducers) { if (mNoReportMetricIds.find(producer->getMetricId()) == mNoReportMetricIds.end()) { uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS); - producer->onDumpReport(dumpTimeStampNs, protoOutput); + producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, protoOutput); protoOutput->end(token); } } diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 9a9b33cc6367..6aa260a0fa7b 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -90,8 +90,8 @@ public: virtual void dropData(const int64_t dropTimeNs); - // Config source owner can call onDumpReport() to get all the metrics collected. virtual void onDumpReport(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, android::util::ProtoOutputStream* protoOutput); // Computes the total byte size of all metrics managed by a single config source. diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index fd623caf6723..51fac8cf54dc 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -147,9 +147,14 @@ void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) { } void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, ProtoOutputStream* protoOutput) { VLOG("metric %lld dump report now...", (long long)mMetricId); - flushIfNeededLocked(dumpTimeNs); + if (include_current_partial_bucket) { + flushLocked(dumpTimeNs); + } else { + flushIfNeededLocked(dumpTimeNs); + } if (mPastBuckets.empty()) { return; } diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index c8f70623294f..b5f642913c52 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -87,6 +87,7 @@ protected: private: void onDumpReportLocked(const int64_t dumpTimeNs, + const bool include_current_partial_bucket, android::util::ProtoOutputStream* protoOutput) override; // Internal interface to handle condition change. diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto index 3b86d2db77b3..36b24c8e89da 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -243,10 +243,10 @@ message StatsdStatsReport { optional int32 matcher_count = 7; optional int32 alert_count = 8; optional bool is_valid = 9; - repeated int32 broadcast_sent_time_sec = 10; repeated int32 data_drop_time_sec = 11; repeated int32 dump_report_time_sec = 12; + repeated int32 dump_report_data_size = 20; repeated MatcherStats matcher_stats = 13; repeated ConditionStats condition_stats = 14; repeated MetricStats metric_stats = 15; diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index 09daf7563796..fb8877a93895 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -139,7 +139,7 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { // Expect to get no metrics, but snapshot specified above in uidmap. vector<uint8_t> bytes; - p.onDumpReport(key, 1, &bytes); + p.onDumpReport(key, 1, false, &bytes); ConfigMetricsReportList output; output.ParseFromArray(bytes.data(), bytes.size()); @@ -167,7 +167,7 @@ TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) { // Expect to get no metrics, but snapshot specified above in uidmap. vector<uint8_t> bytes; - p.onDumpReport(key, 1, &bytes); + p.onDumpReport(key, 1, false, &bytes); ConfigMetricsReportList output; output.ParseFromArray(bytes.data(), bytes.size()); diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp index a97bc4122baf..4dd0da8a67d2 100644 --- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp @@ -144,7 +144,7 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) { } ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); @@ -286,7 +286,7 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) { } ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp index 63e23ce3a941..eb57d47050df 100644 --- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp +++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp @@ -172,7 +172,8 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondi ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, + false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -488,7 +489,8 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationConditi ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, + &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -731,7 +733,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_Combination ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp index c2334d8a3bed..9729a2e8d965 100644 --- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp +++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp @@ -130,7 +130,7 @@ TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCon ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -342,7 +342,7 @@ TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondi ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -521,7 +521,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondit ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -718,7 +718,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationConditio ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp index ab37140577af..4e2c36e12440 100644 --- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp +++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp @@ -142,7 +142,8 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition) { ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, + &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -433,7 +434,8 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition) { ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, + &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -650,7 +652,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp index 2b91324a9d19..18a048520dd2 100644 --- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp +++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp @@ -148,7 +148,7 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) { } ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(1, reports.reports_size()); diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp index 1440f2941c05..1952a6faa4ad 100644 --- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp @@ -200,7 +200,7 @@ TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) { } ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); @@ -314,7 +314,7 @@ TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) { ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp index bfae8bca697f..f2d47c7ab770 100644 --- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp @@ -127,7 +127,7 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) FeedEvents(config, processor); vector<uint8_t> buffer; ConfigMetricsReportList reports; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -161,7 +161,7 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) vector<uint8_t> buffer; ConfigMetricsReportList reports; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); @@ -208,7 +208,7 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) processor->OnLogEvent(event.get()); } - processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); @@ -237,7 +237,7 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) FeedEvents(config, processor); ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); @@ -262,7 +262,7 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) FeedEvents(config, processor); ConfigMetricsReportList reports; vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); @@ -304,7 +304,7 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) processor->OnLogEvent(event.get()); } - processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, &buffer); + processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, &buffer); EXPECT_TRUE(buffer.size() > 0); EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); EXPECT_EQ(reports.reports_size(), 1); diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp index 5c35d96a5ce8..e99e40286a6a 100644 --- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp +++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp @@ -129,9 +129,9 @@ TEST(StatsdStatsTest, TestSubStats) { stats.noteDataDropped(key); // dump report -> 3 - stats.noteMetricsReportSent(key); - stats.noteMetricsReportSent(key); - stats.noteMetricsReportSent(key); + stats.noteMetricsReportSent(key, 0); + stats.noteMetricsReportSent(key, 0); + stats.noteMetricsReportSent(key, 0); vector<uint8_t> output; stats.dumpStats(&output, true); // Dump and reset stats @@ -143,6 +143,7 @@ TEST(StatsdStatsTest, TestSubStats) { EXPECT_EQ(2, configReport.broadcast_sent_time_sec_size()); EXPECT_EQ(1, configReport.data_drop_time_sec_size()); EXPECT_EQ(3, configReport.dump_report_time_sec_size()); + EXPECT_EQ(3, configReport.dump_report_data_size_size()); EXPECT_EQ(1, configReport.annotation_size()); EXPECT_EQ(123, configReport.annotation(0).field_int64()); EXPECT_EQ(456, configReport.annotation(0).field_int32()); @@ -268,7 +269,7 @@ TEST(StatsdStatsTest, TestTimestampThreshold) { for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) { stats.noteDataDropped(key, timestamps[i]); stats.noteBroadcastSent(key, timestamps[i]); - stats.noteMetricsReportSent(key, timestamps[i]); + stats.noteMetricsReportSent(key, 0, timestamps[i]); } int32_t newTimestamp = 10000; @@ -276,7 +277,7 @@ TEST(StatsdStatsTest, TestTimestampThreshold) { // now it should trigger removing oldest timestamp stats.noteDataDropped(key, 10000); stats.noteBroadcastSent(key, 10000); - stats.noteMetricsReportSent(key, 10000); + stats.noteMetricsReportSent(key, 0, 10000); EXPECT_TRUE(stats.mConfigStats.find(key) != stats.mConfigStats.end()); const auto& configStats = stats.mConfigStats[key]; @@ -284,7 +285,7 @@ TEST(StatsdStatsTest, TestTimestampThreshold) { size_t maxCount = StatsdStats::kMaxTimestampCount; EXPECT_EQ(maxCount, configStats->broadcast_sent_time_sec.size()); EXPECT_EQ(maxCount, configStats->data_drop_time_sec.size()); - EXPECT_EQ(maxCount, configStats->dump_report_time_sec.size()); + EXPECT_EQ(maxCount, configStats->dump_report_stats.size()); // the oldest timestamp is the second timestamp in history EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front()); @@ -294,7 +295,7 @@ TEST(StatsdStatsTest, TestTimestampThreshold) { // the last timestamp is the newest timestamp. EXPECT_EQ(newTimestamp, configStats->broadcast_sent_time_sec.back()); EXPECT_EQ(newTimestamp, configStats->data_drop_time_sec.back()); - EXPECT_EQ(newTimestamp, configStats->dump_report_time_sec.back()); + EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first); } } // namespace statsd diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 479fe279c81e..bf17d7079b1e 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -2,8 +2,8 @@ Landroid/accounts/AccountManager;->mContext:Landroid/content/Context; Landroid/accounts/IAccountAuthenticatorResponse$Stub;-><init>()V Landroid/accounts/IAccountManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManager; Landroid/accounts/IAccountManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/animation/LayoutTransition;->cancel()V Landroid/animation/LayoutTransition;->cancel(I)V +Landroid/animation/LayoutTransition;->cancel()V Landroid/animation/ValueAnimator;->animateValue(F)V Landroid/animation/ValueAnimator;->sDurationScale:F Landroid/app/Activity;->getActivityOptions()Landroid/app/ActivityOptions; @@ -190,6 +190,7 @@ Landroid/app/AppOpsManager$OpEntry;->getRejectTime()J Landroid/app/AppOpsManager;->OP_FINE_LOCATION:I Landroid/app/AppOpsManager;->OP_GET_USAGE_STATS:I Landroid/app/AppOpsManager;->OP_POST_NOTIFICATION:I +Landroid/app/AppOpsManager;->OP_PROJECT_MEDIA:I Landroid/app/AppOpsManager;->OP_READ_CONTACTS:I Landroid/app/AppOpsManager;->OP_READ_PHONE_STATE:I Landroid/app/AppOpsManager;->OP_READ_SMS:I @@ -660,6 +661,7 @@ Landroid/content/UriMatcher;->mText:Ljava/lang/String; Landroid/database/AbstractCursor;->mExtras:Landroid/os/Bundle; Landroid/database/AbstractCursor;->mNotifyUri:Landroid/net/Uri; Landroid/database/AbstractCursor;->mRowIdColumnIndex:I +Landroid/database/AbstractWindowedCursor;->clearOrCreateWindow(Ljava/lang/String;)V Landroid/database/CursorWindow;->mWindowPtr:J Landroid/database/CursorWindow;->sCursorWindowSize:I Landroid/database/CursorWindow;->sWindowToPidMap:Landroid/util/LongSparseArray; @@ -668,12 +670,14 @@ Landroid/database/sqlite/SQLiteCustomFunction;->dispatchCallback([Ljava/lang/Str Landroid/database/sqlite/SQLiteCustomFunction;->name:Ljava/lang/String; Landroid/database/sqlite/SQLiteCustomFunction;->numArgs:I Landroid/database/sqlite/SQLiteDatabaseConfiguration;->maxSqlCacheSize:I +Landroid/database/sqlite/SQLiteDatabase;->CONFLICT_VALUES:[Ljava/lang/String; Landroid/database/sqlite/SQLiteDatabase;->mConfigurationLocked:Landroid/database/sqlite/SQLiteDatabaseConfiguration; Landroid/database/sqlite/SQLiteDatabase;->mConnectionPoolLocked:Landroid/database/sqlite/SQLiteConnectionPool; Landroid/database/sqlite/SQLiteDebug$PagerStats;->largestMemAlloc:I Landroid/database/sqlite/SQLiteDebug$PagerStats;->memoryUsed:I Landroid/database/sqlite/SQLiteDebug$PagerStats;->pageCacheOverflow:I Landroid/database/sqlite/SQLiteOpenHelper;->mName:Ljava/lang/String; +Landroid/database/sqlite/SQLiteStatement;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;)V Landroid/ddm/DdmHandleAppName;->getAppName()Ljava/lang/String; Landroid/graphics/AvoidXfermode$Mode;->AVOID:Landroid/graphics/AvoidXfermode$Mode; Landroid/graphics/AvoidXfermode$Mode;->TARGET:Landroid/graphics/AvoidXfermode$Mode; @@ -1019,6 +1023,7 @@ Landroid/media/AudioSystem;->dynamicPolicyCallbackFromNative(ILjava/lang/String; Landroid/media/AudioSystem;->errorCallbackFromNative(I)V Landroid/media/AudioSystem;->getPrimaryOutputFrameCount()I Landroid/media/AudioSystem;->getPrimaryOutputSamplingRate()I +Landroid/media/AudioSystem;->isSourceActive(I)Z Landroid/media/AudioSystem;->isStreamActive(II)Z Landroid/media/AudioSystem;->recordingCallbackFromNative(IIII[I)V Landroid/media/AudioSystem;->setDeviceConnectionState(IILjava/lang/String;Ljava/lang/String;)I @@ -1208,6 +1213,9 @@ Landroid/net/SSLCertificateSocketFactory;->setSoWriteTimeout(Ljava/net/Socket;I) Landroid/net/SSLCertificateSocketFactory;->TAG:Ljava/lang/String; Landroid/net/SSLCertificateSocketFactory;->verifyHostname(Ljava/net/Socket;Ljava/lang/String;)V Landroid/net/SSLSessionCache;->mSessionCache:Lcom/android/org/conscrypt/SSLClientSessionCache; +Landroid/net/StaticIpConfiguration;->gateway:Ljava/net/InetAddress; +Landroid/net/StaticIpConfiguration;-><init>()V +Landroid/net/StaticIpConfiguration;->ipAddress:Landroid/net/LinkAddress; Landroid/net/TrafficStats;->getMobileIfaces()[Ljava/lang/String; Landroid/net/TrafficStats;->getRxBytes(Ljava/lang/String;)J Landroid/net/TrafficStats;->getStatsService()Landroid/net/INetworkStatsService; @@ -1220,11 +1228,11 @@ Landroid/net/wifi/p2p/WifiP2pGroupList;->getGroupList()Ljava/util/Collection; Landroid/net/wifi/p2p/WifiP2pGroup;->TEMPORARY_NET_ID:I Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel; Landroid/net/wifi/p2p/WifiP2pManager$Channel;->putListener(Ljava/lang/Object;)I +Landroid/net/wifi/p2p/WifiP2pManager;->CREATE_GROUP:I Landroid/net/wifi/p2p/WifiP2pManager;->deletePersistentGroup(Landroid/net/wifi/p2p/WifiP2pManager$Channel;ILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V Landroid/net/wifi/p2p/WifiP2pManager;->requestPersistentGroupInfo(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;)V Landroid/net/wifi/p2p/WifiP2pManager;->setDeviceName(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Ljava/lang/String;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V Landroid/net/wifi/p2p/WifiP2pManager;->setWifiP2pChannels(Landroid/net/wifi/p2p/WifiP2pManager$Channel;IILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V -Landroid/net/wifi/p2p/WifiP2pManager;->CREATE_GROUP:I Landroid/net/wifi/ScanResult;->anqpDomainId:I Landroid/net/wifi/ScanResult;->anqpLines:Ljava/util/List; Landroid/net/wifi/ScanResult;->distanceCm:I @@ -1256,6 +1264,8 @@ Landroid/net/wifi/WifiConfiguration;->apChannel:I Landroid/net/wifi/WifiConfiguration;->defaultGwMacAddress:Ljava/lang/String; Landroid/net/wifi/WifiConfiguration;->lastConnectUid:I Landroid/net/wifi/WifiConfiguration;->mIpConfiguration:Landroid/net/IpConfiguration; +Landroid/net/wifi/WifiConfiguration;->setIpAssignment(Landroid/net/IpConfiguration$IpAssignment;)V +Landroid/net/wifi/WifiConfiguration;->setStaticIpConfiguration(Landroid/net/StaticIpConfiguration;)V Landroid/net/wifi/WifiConfiguration;->validatedInternetAccess:Z Landroid/net/wifi/WifiEnterpriseConfig;->getCaCertificateAlias()Ljava/lang/String; Landroid/net/wifi/WifiEnterpriseConfig;->getClientCertificateAlias()Ljava/lang/String; @@ -1591,6 +1601,7 @@ Landroid/provider/Browser;->clearHistory(Landroid/content/ContentResolver;)V Landroid/provider/Browser;->clearSearches(Landroid/content/ContentResolver;)V Landroid/provider/Browser;->deleteFromHistory(Landroid/content/ContentResolver;Ljava/lang/String;)V Landroid/provider/Browser;->getVisitedHistory(Landroid/content/ContentResolver;)[Ljava/lang/String; +Landroid/provider/Browser;->HISTORY_PROJECTION:[Ljava/lang/String; Landroid/provider/Browser;->SEARCHES_URI:Landroid/net/Uri; Landroid/provider/Browser;->sendString(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V Landroid/provider/Browser;->updateVisitedHistory(Landroid/content/ContentResolver;Ljava/lang/String;Z)V @@ -2080,7 +2091,9 @@ Landroid/view/accessibility/AccessibilityManager;->mIsEnabled:Z Landroid/view/accessibility/AccessibilityManager;->mIsHighTextContrastEnabled:Z Landroid/view/accessibility/AccessibilityManager;->sInstance:Landroid/view/accessibility/AccessibilityManager; Landroid/view/accessibility/AccessibilityManager;->sInstanceSync:Ljava/lang/Object; +Landroid/view/accessibility/AccessibilityNodeInfo;->isSealed()Z Landroid/view/accessibility/AccessibilityNodeInfo;->refresh(Landroid/os/Bundle;Z)Z +Landroid/view/accessibility/AccessibilityNodeInfo;->setSealed(Z)V Landroid/view/accessibility/AccessibilityRecord;->getSourceNodeId()J Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List; Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager; @@ -2522,6 +2535,7 @@ Landroid/widget/HorizontalScrollView;->mChildToScrollTo:Landroid/view/View; Landroid/widget/HorizontalScrollView;->mEdgeGlowLeft:Landroid/widget/EdgeEffect; Landroid/widget/HorizontalScrollView;->mEdgeGlowRight:Landroid/widget/EdgeEffect; Landroid/widget/HorizontalScrollView;->mScroller:Landroid/widget/OverScroller; +Landroid/widget/ImageView;->animateTransform(Landroid/graphics/Matrix;)V Landroid/widget/ImageView;->mAdjustViewBounds:Z Landroid/widget/ImageView;->mAlpha:I Landroid/widget/ImageView;->mDrawMatrix:Landroid/graphics/Matrix; @@ -3000,6 +3014,8 @@ Lcom/android/internal/telephony/ITelephony;->endCall()Z Lcom/android/internal/telephony/ITelephony;->getCallState()I Lcom/android/internal/telephony/ITelephony;->getDataState()I Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z +Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V +Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry; Lcom/android/internal/telephony/ITelephony;->silenceRinger()V Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony; Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCall()Z @@ -3183,6 +3199,7 @@ Ljava/lang/Daemons;->stop()V Ljava/lang/Double;->value:D Ljava/lang/Float;->value:F Ljava/lang/Integer;->value:I +Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V Ljava/lang/Long;->value:J Ljava/lang/ref/FinalizerReference;->add(Ljava/lang/Object;)V Ljava/lang/ref/FinalizerReference;->head:Ljava/lang/ref/FinalizerReference; diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt index f3bc206090c9..b598296d3df0 100644 --- a/config/hiddenapi-vendor-list.txt +++ b/config/hiddenapi-vendor-list.txt @@ -312,9 +312,7 @@ Landroid/net/SntpClient;->getRoundTripTime()J Landroid/net/SntpClient;->requestTime(Ljava/lang/String;I)Z Landroid/net/StaticIpConfiguration;->dnsServers:Ljava/util/ArrayList; Landroid/net/StaticIpConfiguration;->domains:Ljava/lang/String; -Landroid/net/StaticIpConfiguration;->gateway:Ljava/net/InetAddress; Landroid/net/StaticIpConfiguration;->getRoutes(Ljava/lang/String;)Ljava/util/List; -Landroid/net/StaticIpConfiguration;->ipAddress:Landroid/net/LinkAddress; Landroid/net/StringNetworkSpecifier;->specifier:Ljava/lang/String; Landroid/net/TrafficStats;->getMobileTcpRxPackets()J Landroid/net/TrafficStats;->getMobileTcpTxPackets()J @@ -717,6 +715,7 @@ Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjav Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V Lcom/android/ims/internal/uce/presence/PresCapInfo;->getCapInfo()Lcom/android/ims/internal/uce/common/CapInfo; Lcom/android/ims/internal/uce/presence/PresCapInfo;->getContactUri()Ljava/lang/String; +Lcom/android/ims/internal/uce/presence/PresCapInfo;->mContactUri:Ljava/lang/String; Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getMediaType()I Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceDesc()Ljava/lang/String; Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceId()Ljava/lang/String; diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index b6cff385d752..69c3632b7ab2 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -32,6 +32,7 @@ public class BroadcastOptions { private long mTemporaryAppWhitelistDuration; private int mMinManifestReceiverApiLevel = 0; private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT; + private boolean mDontSendToRestrictedApps = false; /** * How long to temporarily put an app on the power whitelist when executing this broadcast @@ -52,6 +53,12 @@ public class BroadcastOptions { static final String KEY_MAX_MANIFEST_RECEIVER_API_LEVEL = "android:broadcast.maxManifestReceiverApiLevel"; + /** + * Corresponds to {@link #setMaxManifestReceiverApiLevel}. + */ + static final String KEY_DONT_SEND_TO_RESTRICTED_APPS = + "android:broadcast.dontSendToRestrictedApps"; + public static BroadcastOptions makeBasic() { BroadcastOptions opts = new BroadcastOptions(); return opts; @@ -66,6 +73,7 @@ public class BroadcastOptions { mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0); mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, Build.VERSION_CODES.CUR_DEVELOPMENT); + mDontSendToRestrictedApps = opts.getBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, false); } /** @@ -123,6 +131,23 @@ public class BroadcastOptions { } /** + * Sets whether pending intent can be sent for an application with background restrictions + * @param dontSendToRestrictedApps if true, pending intent will not be sent for an application + * with background restrictions. Default value is {@code false} + */ + public void setDontSendToRestrictedApps(boolean dontSendToRestrictedApps) { + mDontSendToRestrictedApps = dontSendToRestrictedApps; + } + + /** + * @hide + * @return #setDontSendToRestrictedApps + */ + public boolean isDontSendToRestrictedApps() { + return mDontSendToRestrictedApps; + } + + /** * Returns the created options as a Bundle, which can be passed to * {@link android.content.Context#sendBroadcast(android.content.Intent) * Context.sendBroadcast(Intent)} and related methods. @@ -141,6 +166,9 @@ public class BroadcastOptions { if (mMaxManifestReceiverApiLevel != Build.VERSION_CODES.CUR_DEVELOPMENT) { b.putInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, mMaxManifestReceiverApiLevel); } + if (mDontSendToRestrictedApps) { + b.putBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, true); + } return b.isEmpty() ? null : b; } } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index e7b6cf0e5dd1..4ab6724262ce 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3902,7 +3902,7 @@ public class Notification implements Parcelable * @deprecated use {@link #addPerson(Person)} */ public Builder addPerson(String uri) { - addPerson(new Person().setUri(uri)); + addPerson(new Person.Builder().setUri(uri).build()); return this; } @@ -6384,7 +6384,7 @@ public class Notification implements Parcelable * @deprecated use {@code MessagingStyle(Person)} */ public MessagingStyle(@NonNull CharSequence userDisplayName) { - this(new Person().setName(userDisplayName)); + this(new Person.Builder().setName(userDisplayName).build()); } /** @@ -6490,7 +6490,7 @@ public class Notification implements Parcelable */ public MessagingStyle addMessage(CharSequence text, long timestamp, CharSequence sender) { return addMessage(text, timestamp, - sender == null ? null : new Person().setName(sender)); + sender == null ? null : new Person.Builder().setName(sender).build()); } /** @@ -6663,7 +6663,7 @@ public class Notification implements Parcelable mUser = extras.getParcelable(EXTRA_MESSAGING_PERSON); if (mUser == null) { CharSequence displayName = extras.getCharSequence(EXTRA_SELF_DISPLAY_NAME); - mUser = new Person().setName(displayName); + mUser = new Person.Builder().setName(displayName).build(); } mConversationTitle = extras.getCharSequence(EXTRA_CONVERSATION_TITLE); Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES); @@ -6918,7 +6918,8 @@ public class Notification implements Parcelable * @deprecated use {@code Message(CharSequence, long, Person)} */ public Message(CharSequence text, long timestamp, CharSequence sender){ - this(text, timestamp, sender == null ? null : new Person().setName(sender)); + this(text, timestamp, sender == null ? null + : new Person.Builder().setName(sender).build()); } /** @@ -6929,10 +6930,11 @@ public class Notification implements Parcelable * Should be <code>null</code> for messages by the current user, in which case * the platform will insert the user set in {@code MessagingStyle(Person)}. * <p> - * The person provided should contain an Icon, set with {@link Person#setIcon(Icon)} - * and also have a name provided with {@link Person#setName(CharSequence)}. If multiple - * users have the same name, consider providing a key with {@link Person#setKey(String)} - * in order to differentiate between the different users. + * The person provided should contain an Icon, set with + * {@link Person.Builder#setIcon(Icon)} and also have a name provided + * with {@link Person.Builder#setName(CharSequence)}. If multiple users have the same + * name, consider providing a key with {@link Person.Builder#setKey(String)} in order + * to differentiate between the different users. * </p> */ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender) { @@ -7094,7 +7096,7 @@ public class Notification implements Parcelable // the native api instead CharSequence senderName = bundle.getCharSequence(KEY_SENDER); if (senderName != null) { - senderPerson = new Person().setName(senderName); + senderPerson = new Person.Builder().setName(senderName).build(); } } Message message = new Message(bundle.getCharSequence(KEY_TEXT), @@ -7789,217 +7791,6 @@ public class Notification implements Parcelable } } - /** - * A Person associated with this Notification. - */ - public static final class Person implements Parcelable { - @Nullable private CharSequence mName; - @Nullable private Icon mIcon; - @Nullable private String mUri; - @Nullable private String mKey; - private boolean mBot; - private boolean mImportant; - - protected Person(Parcel in) { - mName = in.readCharSequence(); - if (in.readInt() != 0) { - mIcon = Icon.CREATOR.createFromParcel(in); - } - mUri = in.readString(); - mKey = in.readString(); - mImportant = in.readBoolean(); - mBot = in.readBoolean(); - } - - /** - * Create a new person. - */ - public Person() { - } - - /** - * Give this person a name. - * - * @param name the name of this person - */ - public Person setName(@Nullable CharSequence name) { - this.mName = name; - return this; - } - - /** - * Add an icon for this person. - * <br /> - * This is currently only used for {@link MessagingStyle} notifications and should not be - * provided otherwise, in order to save memory. The system will prefer this icon over any - * images that are resolved from the URI. - * - * @param icon the icon of the person - */ - public Person setIcon(@Nullable Icon icon) { - this.mIcon = icon; - return this; - } - - /** - * Set a URI associated with this person. - * - * <P> - * Depending on user preferences, adding a URI to a Person may allow the notification to - * pass through interruption filters, if this notification is of - * category {@link #CATEGORY_CALL} or {@link #CATEGORY_MESSAGE}. - * The addition of people may also cause this notification to appear more prominently in - * the user interface. - * </P> - * - * <P> - * The person should be specified by the {@code String} representation of a - * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}. - * </P> - * - * <P>The system will also attempt to resolve {@code mailto:} and {@code tel:} schema - * URIs. The path part of these URIs must exist in the contacts database, in the - * appropriate column, or the reference will be discarded as invalid. Telephone schema - * URIs will be resolved by {@link android.provider.ContactsContract.PhoneLookup}. - * </P> - * - * @param uri a URI for the person - */ - public Person setUri(@Nullable String uri) { - mUri = uri; - return this; - } - - /** - * Add a key to this person in order to uniquely identify it. - * This is especially useful if the name doesn't uniquely identify this person or if the - * display name is a short handle of the actual name. - * - * <P>If no key is provided, the name serves as as the key for the purpose of - * identification.</P> - * - * @param key the key that uniquely identifies this person - */ - public Person setKey(@Nullable String key) { - mKey = key; - return this; - } - - /** - * Sets whether this is an important person. Use this method to denote users who frequently - * interact with the user of this device, when it is not possible to refer to the user - * by {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}. - * - * @param isImportant {@code true} if this is an important person, {@code false} otherwise. - */ - public Person setImportant(boolean isImportant) { - mImportant = isImportant; - return this; - } - - /** - * Sets whether this person is a machine rather than a human. - * - * @param isBot {@code true} if this person is a machine, {@code false} otherwise. - */ - public Person setBot(boolean isBot) { - mBot = isBot; - return this; - } - - /** - * @return the uri provided for this person or {@code null} if no Uri was provided - */ - @Nullable - public String getUri() { - return mUri; - } - - /** - * @return the name provided for this person or {@code null} if no name was provided - */ - @Nullable - public CharSequence getName() { - return mName; - } - - /** - * @return the icon provided for this person or {@code null} if no icon was provided - */ - @Nullable - public Icon getIcon() { - return mIcon; - } - - /** - * @return the key provided for this person or {@code null} if no key was provided - */ - @Nullable - public String getKey() { - return mKey; - } - - /** - * @return whether this Person is a machine. - */ - public boolean isBot() { - return mBot; - } - - /** - * @return whether this Person is important. - */ - public boolean isImportant() { - return mImportant; - } - - /** - * @return the URI associated with this person, or "name:mName" otherwise - * @hide - */ - public String resolveToLegacyUri() { - if (mUri != null) { - return mUri; - } - if (mName != null) { - return "name:" + mName; - } - return ""; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, @WriteFlags int flags) { - dest.writeCharSequence(mName); - if (mIcon != null) { - dest.writeInt(1); - mIcon.writeToParcel(dest, 0); - } else { - dest.writeInt(0); - } - dest.writeString(mUri); - dest.writeString(mKey); - dest.writeBoolean(mImportant); - dest.writeBoolean(mBot); - } - - public static final Creator<Person> CREATOR = new Creator<Person>() { - @Override - public Person createFromParcel(Parcel in) { - return new Person(in); - } - - @Override - public Person[] newArray(int size) { - return new Person[size]; - } - }; - } - // When adding a new Style subclass here, don't forget to update // Builder.getNotificationStyleClass. diff --git a/core/java/android/app/Person.java b/core/java/android/app/Person.java new file mode 100644 index 000000000000..3884a8d49dd1 --- /dev/null +++ b/core/java/android/app/Person.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 android.app; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.drawable.Icon; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Provides an immutable reference to an entity that appears repeatedly on different surfaces of the + * platform. For example, this could represent the sender of a message. + */ +public final class Person implements Parcelable { + + @Nullable private CharSequence mName; + @Nullable private Icon mIcon; + @Nullable private String mUri; + @Nullable private String mKey; + private boolean mIsBot; + private boolean mIsImportant; + + private Person(Parcel in) { + mName = in.readCharSequence(); + if (in.readInt() != 0) { + mIcon = Icon.CREATOR.createFromParcel(in); + } + mUri = in.readString(); + mKey = in.readString(); + mIsImportant = in.readBoolean(); + mIsBot = in.readBoolean(); + } + + private Person(Builder builder) { + mName = builder.mName; + mIcon = builder.mIcon; + mUri = builder.mUri; + mKey = builder.mKey; + mIsBot = builder.mIsBot; + mIsImportant = builder.mIsImportant; + } + + /** Creates and returns a new {@link Builder} initialized with this Person's data. */ + public Builder toBuilder() { + return new Builder(this); + } + + /** + * @return the uri provided for this person or {@code null} if no Uri was provided. + */ + @Nullable + public String getUri() { + return mUri; + } + + /** + * @return the name provided for this person or {@code null} if no name was provided. + */ + @Nullable + public CharSequence getName() { + return mName; + } + + /** + * @return the icon provided for this person or {@code null} if no icon was provided. + */ + @Nullable + public Icon getIcon() { + return mIcon; + } + + /** + * @return the key provided for this person or {@code null} if no key was provided. + */ + @Nullable + public String getKey() { + return mKey; + } + + /** + * @return whether this Person is a machine. + */ + public boolean isBot() { + return mIsBot; + } + + /** + * @return whether this Person is important. + */ + public boolean isImportant() { + return mIsImportant; + } + + /** + * @return the URI associated with this person, or "name:mName" otherwise + * @hide + */ + public String resolveToLegacyUri() { + if (mUri != null) { + return mUri; + } + if (mName != null) { + return "name:" + mName; + } + return ""; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, @WriteFlags int flags) { + dest.writeCharSequence(mName); + if (mIcon != null) { + dest.writeInt(1); + mIcon.writeToParcel(dest, 0); + } else { + dest.writeInt(0); + } + dest.writeString(mUri); + dest.writeString(mKey); + dest.writeBoolean(mIsImportant); + dest.writeBoolean(mIsBot); + } + + /** Builder for the immutable {@link Person} class. */ + public static class Builder { + @Nullable private CharSequence mName; + @Nullable private Icon mIcon; + @Nullable private String mUri; + @Nullable private String mKey; + private boolean mIsBot; + private boolean mIsImportant; + + /** Creates a new, empty {@link Builder}. */ + public Builder() { + } + + private Builder(Person person) { + mName = person.mName; + mIcon = person.mIcon; + mUri = person.mUri; + mKey = person.mKey; + mIsBot = person.mIsBot; + mIsImportant = person.mIsImportant; + } + + /** + * Give this person a name. + * + * @param name the name of this person. + */ + @NonNull + public Person.Builder setName(@Nullable CharSequence name) { + this.mName = name; + return this; + } + + /** + * Add an icon for this person. + * <br /> + * The system will prefer this icon over any images that are resolved from the URI. + * + * @param icon the icon of the person. + */ + @NonNull + public Person.Builder setIcon(@Nullable Icon icon) { + this.mIcon = icon; + return this; + } + + /** + * Set a URI associated with this person. + * + * <P> + * The person should be specified by the {@code String} representation of a + * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}. + * </P> + * + * <P>The system will also attempt to resolve {@code mailto:} and {@code tel:} schema + * URIs. The path part of these URIs must exist in the contacts database, in the + * appropriate column, or the reference will be discarded as invalid. Telephone schema + * URIs will be resolved by {@link android.provider.ContactsContract.PhoneLookup}. + * </P> + * + * @param uri a URI for the person. + */ + @NonNull + public Person.Builder setUri(@Nullable String uri) { + mUri = uri; + return this; + } + + /** + * Add a key to this person in order to uniquely identify it. + * This is especially useful if the name doesn't uniquely identify this person or if the + * display name is a short handle of the actual name. + * + * <P>If no key is provided, the name serves as the key for the purpose of + * identification.</P> + * + * @param key the key that uniquely identifies this person. + */ + @NonNull + public Person.Builder setKey(@Nullable String key) { + mKey = key; + return this; + } + + /** + * Sets whether this is an important person. Use this method to denote users who frequently + * interact with the user of this device when {@link #setUri(String)} isn't provided with + * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}, and instead with + * the {@code mailto:} or {@code tel:} schemas. + * + * @param isImportant {@code true} if this is an important person, {@code false} otherwise. + */ + @NonNull + public Person.Builder setImportant(boolean isImportant) { + mIsImportant = isImportant; + return this; + } + + /** + * Sets whether this person is a machine rather than a human. + * + * @param isBot {@code true} if this person is a machine, {@code false} otherwise. + */ + @NonNull + public Person.Builder setBot(boolean isBot) { + mIsBot = isBot; + return this; + } + + /** Creates and returns the {@link Person} this builder represents. */ + @NonNull + public Person build() { + return new Person(this); + } + } + + public static final Creator<Person> CREATOR = new Creator<Person>() { + @Override + public Person createFromParcel(Parcel in) { + return new Person(in); + } + + @Override + public Person[] newArray(int size) { + return new Person[size]; + } + }; +} diff --git a/core/java/android/app/admin/FreezeInterval.java b/core/java/android/app/admin/FreezePeriod.java index de5e21ac75c4..657f0177097e 100644 --- a/core/java/android/app/admin/FreezeInterval.java +++ b/core/java/android/app/admin/FreezePeriod.java @@ -20,49 +20,88 @@ import android.util.Log; import android.util.Pair; import java.time.LocalDate; +import java.time.MonthDay; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; /** - * An interval representing one freeze period which repeats annually. We use the number of days - * since the start of (non-leap) year to define the start and end dates of an interval, both - * inclusive. If the end date is smaller than the start date, the interval is considered wrapped - * around the year-end. As far as an interval is concerned, February 29th should be treated as - * if it were February 28th: so an interval starting or ending on February 28th are not - * distinguishable from an interval on February 29th. When calulating interval length or - * distance between two dates, February 29th is also disregarded. + * A class that represents one freeze period which repeats <em>annually</em>. A freeze period has + * two {@link java.time#MonthDay} values that define the start and end dates of the period, both + * inclusive. If the end date is earlier than the start date, the period is considered wrapped + * around the year-end. As far as freeze period is concerned, leap year is disregarded and February + * 29th should be treated as if it were February 28th: so a freeze starting or ending on February + * 28th is identical to a freeze starting or ending on February 29th. When calulating the length of + * a freeze or the distance bewteen two freee periods, February 29th is also ignored. * * @see SystemUpdatePolicy#setFreezePeriods - * @hide */ -public class FreezeInterval { - private static final String TAG = "FreezeInterval"; +public class FreezePeriod { + private static final String TAG = "FreezePeriod"; private static final int DUMMY_YEAR = 2001; static final int DAYS_IN_YEAR = 365; // 365 since DUMMY_YEAR is not a leap year - final int mStartDay; // [1,365] - final int mEndDay; // [1,365] + private final MonthDay mStart; + private final MonthDay mEnd; - FreezeInterval(int startDay, int endDay) { - if (startDay < 1 || startDay > 365 || endDay < 1 || endDay > 365) { - throw new RuntimeException("Bad dates for Interval: " + startDay + "," + endDay); - } + /* + * Start and end dates represented by number of days since the beginning of the year. + * They are internal representations of mStart and mEnd with normalized Leap year days + * (Feb 29 == Feb 28 == 59th day of year). All internal calclations are based on + * these two values so that leap year days are disregarded. + */ + private final int mStartDay; // [1, 365] + private final int mEndDay; // [1, 365] + + /** + * Creates a freeze period by its start and end dates. If the end date is earlier than the start + * date, the freeze period is considered wrapping year-end. + */ + public FreezePeriod(MonthDay start, MonthDay end) { + mStart = start; + mStartDay = mStart.atYear(DUMMY_YEAR).getDayOfYear(); + mEnd = end; + mEndDay = mEnd.atYear(DUMMY_YEAR).getDayOfYear(); + } + + /** + * Returns the start date (inclusive) of this freeze period. + */ + public MonthDay getStart() { + return mStart; + } + + /** + * Returns the end date (inclusive) of this freeze period. + */ + public MonthDay getEnd() { + return mEnd; + } + + /** + * @hide + */ + private FreezePeriod(int startDay, int endDay) { mStartDay = startDay; + mStart = dayOfYearToMonthDay(startDay); mEndDay = endDay; + mEnd = dayOfYearToMonthDay(endDay); } + /** @hide */ int getLength() { return getEffectiveEndDay() - mStartDay + 1; } + /** @hide */ boolean isWrapped() { return mEndDay < mStartDay; } /** * Returns the effective end day, taking wrapping around year-end into consideration + * @hide */ int getEffectiveEndDay() { if (!isWrapped()) { @@ -72,6 +111,7 @@ public class FreezeInterval { } } + /** @hide */ boolean contains(LocalDate localDate) { final int daysOfYear = dayOfYearDisregardLeapYear(localDate); if (!isWrapped()) { @@ -84,6 +124,7 @@ public class FreezeInterval { } } + /** @hide */ boolean after(LocalDate localDate) { return mStartDay > dayOfYearDisregardLeapYear(localDate); } @@ -95,6 +136,7 @@ public class FreezeInterval { * include now, the returned dates represents the next future interval. * The result will always have the same month and dayOfMonth value as the non-instantiated * interval itself. + * @hide */ Pair<LocalDate, LocalDate> toCurrentOrFutureRealDates(LocalDate now) { final int nowDays = dayOfYearDisregardLeapYear(now); @@ -138,14 +180,24 @@ public class FreezeInterval { + LocalDate.ofYearDay(DUMMY_YEAR, mEndDay).format(formatter); } - // Treat the supplied date as in a non-leap year and return its day of year. - static int dayOfYearDisregardLeapYear(LocalDate date) { + /** @hide */ + private static MonthDay dayOfYearToMonthDay(int dayOfYear) { + LocalDate date = LocalDate.ofYearDay(DUMMY_YEAR, dayOfYear); + return MonthDay.of(date.getMonth(), date.getDayOfMonth()); + } + + /** + * Treat the supplied date as in a non-leap year and return its day of year. + * @hide + */ + private static int dayOfYearDisregardLeapYear(LocalDate date) { return date.withYear(DUMMY_YEAR).getDayOfYear(); } /** * Compute the number of days between first (inclusive) and second (exclusive), * treating all years in between as non-leap. + * @hide */ public static int distanceWithoutLeapYear(LocalDate first, LocalDate second) { return dayOfYearDisregardLeapYear(first) - dayOfYearDisregardLeapYear(second) @@ -165,16 +217,16 @@ public class FreezeInterval { * 3. At most one wrapped Interval remains, and it will be at the end of the list * @hide */ - protected static List<FreezeInterval> canonicalizeIntervals(List<FreezeInterval> intervals) { + static List<FreezePeriod> canonicalizePeriods(List<FreezePeriod> intervals) { boolean[] taken = new boolean[DAYS_IN_YEAR]; // First convert the intervals into flat array - for (FreezeInterval interval : intervals) { + for (FreezePeriod interval : intervals) { for (int i = interval.mStartDay; i <= interval.getEffectiveEndDay(); i++) { taken[(i - 1) % DAYS_IN_YEAR] = true; } } // Then reconstruct intervals from the array - List<FreezeInterval> result = new ArrayList<>(); + List<FreezePeriod> result = new ArrayList<>(); int i = 0; while (i < DAYS_IN_YEAR) { if (!taken[i]) { @@ -183,14 +235,14 @@ public class FreezeInterval { } final int intervalStart = i + 1; while (i < DAYS_IN_YEAR && taken[i]) i++; - result.add(new FreezeInterval(intervalStart, i)); + result.add(new FreezePeriod(intervalStart, i)); } // Check if the last entry can be merged to the first entry to become one single // wrapped interval final int lastIndex = result.size() - 1; if (lastIndex > 0 && result.get(lastIndex).mEndDay == DAYS_IN_YEAR && result.get(0).mStartDay == 1) { - FreezeInterval wrappedInterval = new FreezeInterval(result.get(lastIndex).mStartDay, + FreezePeriod wrappedInterval = new FreezePeriod(result.get(lastIndex).mStartDay, result.get(0).mEndDay); result.set(lastIndex, wrappedInterval); result.remove(0); @@ -207,18 +259,18 @@ public class FreezeInterval { * * @hide */ - protected static void validatePeriods(List<FreezeInterval> periods) { - List<FreezeInterval> allPeriods = FreezeInterval.canonicalizeIntervals(periods); + static void validatePeriods(List<FreezePeriod> periods) { + List<FreezePeriod> allPeriods = FreezePeriod.canonicalizePeriods(periods); if (allPeriods.size() != periods.size()) { throw SystemUpdatePolicy.ValidationFailedException.duplicateOrOverlapPeriods(); } for (int i = 0; i < allPeriods.size(); i++) { - FreezeInterval current = allPeriods.get(i); + FreezePeriod current = allPeriods.get(i); if (current.getLength() > SystemUpdatePolicy.FREEZE_PERIOD_MAX_LENGTH) { throw SystemUpdatePolicy.ValidationFailedException.freezePeriodTooLong("Freeze " + "period " + current + " is too long: " + current.getLength() + " days"); } - FreezeInterval previous = i > 0 ? allPeriods.get(i - 1) + FreezePeriod previous = i > 0 ? allPeriods.get(i - 1) : allPeriods.get(allPeriods.size() - 1); if (previous != current) { final int separation; @@ -247,7 +299,7 @@ public class FreezeInterval { * * @hide */ - protected static void validateAgainstPreviousFreezePeriod(List<FreezeInterval> periods, + static void validateAgainstPreviousFreezePeriod(List<FreezePeriod> periods, LocalDate prevPeriodStart, LocalDate prevPeriodEnd, LocalDate now) { if (periods.size() == 0 || prevPeriodStart == null || prevPeriodEnd == null) { return; @@ -258,14 +310,14 @@ public class FreezeInterval { // Clock was adjusted backwards. We can continue execution though, the separation // and length validation below still works under this condition. } - List<FreezeInterval> allPeriods = FreezeInterval.canonicalizeIntervals(periods); + List<FreezePeriod> allPeriods = FreezePeriod.canonicalizePeriods(periods); // Given current time now, find the freeze period that's either current, or the one // that's immediately afterwards. For the later case, it might be after the year-end, // but this can only happen if there is only one freeze period. - FreezeInterval curOrNextFreezePeriod = allPeriods.get(0); - for (FreezeInterval interval : allPeriods) { + FreezePeriod curOrNextFreezePeriod = allPeriods.get(0); + for (FreezePeriod interval : allPeriods) { if (interval.contains(now) - || interval.mStartDay > FreezeInterval.dayOfYearDisregardLeapYear(now)) { + || interval.mStartDay > FreezePeriod.dayOfYearDisregardLeapYear(now)) { curOrNextFreezePeriod = interval; break; } @@ -282,7 +334,7 @@ public class FreezeInterval { // Now validate [prevPeriodStart, prevPeriodEnd] against curOrNextFreezeDates final String periodsDescription = "Prev: " + prevPeriodStart + "," + prevPeriodEnd + "; cur: " + curOrNextFreezeDates.first + "," + curOrNextFreezeDates.second; - long separation = FreezeInterval.distanceWithoutLeapYear(curOrNextFreezeDates.first, + long separation = FreezePeriod.distanceWithoutLeapYear(curOrNextFreezeDates.first, prevPeriodEnd) - 1; if (separation > 0) { // Two intervals do not overlap, check separation @@ -292,7 +344,7 @@ public class FreezeInterval { } } else { // Two intervals overlap, check combined length - long length = FreezeInterval.distanceWithoutLeapYear(curOrNextFreezeDates.second, + long length = FreezePeriod.distanceWithoutLeapYear(curOrNextFreezeDates.second, prevPeriodStart) + 1; if (length > SystemUpdatePolicy.FREEZE_PERIOD_MAX_LENGTH) { throw ValidationFailedException.combinedPeriodTooLong("Combined freeze period " diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java index 47b3a81d0174..20eef6cc01d8 100644 --- a/core/java/android/app/admin/SystemUpdatePolicy.java +++ b/core/java/android/app/admin/SystemUpdatePolicy.java @@ -38,9 +38,11 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.MonthDay; import java.time.ZoneId; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -51,7 +53,7 @@ import java.util.stream.Collectors; * @see DevicePolicyManager#setSystemUpdatePolicy * @see DevicePolicyManager#getSystemUpdatePolicy */ -public class SystemUpdatePolicy implements Parcelable { +public final class SystemUpdatePolicy implements Parcelable { private static final String TAG = "SystemUpdatePolicy"; /** @hide */ @@ -163,6 +165,7 @@ public class SystemUpdatePolicy implements Parcelable { ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE, ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG, ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE, + ERROR_UNKNOWN, }) @Retention(RetentionPolicy.SOURCE) @interface ValidationFailureType {} @@ -171,33 +174,38 @@ public class SystemUpdatePolicy implements Parcelable { public static final int ERROR_NONE = 0; /** + * Validation failed with unknown error. + */ + public static final int ERROR_UNKNOWN = 1; + + /** * The freeze periods contains duplicates, periods that overlap with each * other or periods whose start and end joins. */ - public static final int ERROR_DUPLICATE_OR_OVERLAP = 1; + public static final int ERROR_DUPLICATE_OR_OVERLAP = 2; /** * There exists at least one freeze period whose length exceeds 90 days. */ - public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 2; + public static final int ERROR_NEW_FREEZE_PERIOD_TOO_LONG = 3; /** * There exists some freeze period which starts within 60 days of the preceding period's * end time. */ - public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 3; + public static final int ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE = 4; /** * The device has been in a freeze period and when combining with the new freeze period * to be set, it will result in the total freeze period being longer than 90 days. */ - public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 4; + public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG = 5; /** * The device has been in a freeze period and some new freeze period to be set is less * than 60 days from the end of the last freeze period the device went through. */ - public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 5; + public static final int ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE = 6; @ValidationFailureType private final int mErrorCode; @@ -272,7 +280,7 @@ public class SystemUpdatePolicy implements Parcelable { private int mMaintenanceWindowStart; private int mMaintenanceWindowEnd; - private final ArrayList<FreezeInterval> mFreezePeriods; + private final ArrayList<FreezePeriod> mFreezePeriods; private SystemUpdatePolicy() { mPolicyType = TYPE_UNKNOWN; @@ -444,12 +452,10 @@ public class SystemUpdatePolicy implements Parcelable { * requirement set above * @return this instance */ - public SystemUpdatePolicy setFreezePeriods(List<Pair<Integer, Integer>> freezePeriods) { - List<FreezeInterval> newPeriods = freezePeriods.stream().map( - p -> new FreezeInterval(p.first, p.second)).collect(Collectors.toList()); - FreezeInterval.validatePeriods(newPeriods); + public SystemUpdatePolicy setFreezePeriods(List<FreezePeriod> freezePeriods) { + FreezePeriod.validatePeriods(freezePeriods); mFreezePeriods.clear(); - mFreezePeriods.addAll(newPeriods); + mFreezePeriods.addAll(freezePeriods); return this; } @@ -458,12 +464,8 @@ public class SystemUpdatePolicy implements Parcelable { * * @return the list of freeze periods, or an empty list if none was set. */ - public List<Pair<Integer, Integer>> getFreezePeriods() { - List<Pair<Integer, Integer>> result = new ArrayList<>(mFreezePeriods.size()); - for (FreezeInterval interval : mFreezePeriods) { - result.add(new Pair<>(interval.mStartDay, interval.mEndDay)); - } - return result; + public List<FreezePeriod> getFreezePeriods() { + return Collections.unmodifiableList(mFreezePeriods); } /** @@ -472,7 +474,7 @@ public class SystemUpdatePolicy implements Parcelable { * @hide */ public Pair<LocalDate, LocalDate> getCurrentFreezePeriod(LocalDate now) { - for (FreezeInterval interval : mFreezePeriods) { + for (FreezePeriod interval : mFreezePeriods) { if (interval.contains(now)) { return interval.toCurrentOrFutureRealDates(now); } @@ -485,10 +487,10 @@ public class SystemUpdatePolicy implements Parcelable { * is not within a freeze period. */ private long timeUntilNextFreezePeriod(long now) { - List<FreezeInterval> sortedPeriods = FreezeInterval.canonicalizeIntervals(mFreezePeriods); + List<FreezePeriod> sortedPeriods = FreezePeriod.canonicalizePeriods(mFreezePeriods); LocalDate nowDate = millisToDate(now); LocalDate nextFreezeStart = null; - for (FreezeInterval interval : sortedPeriods) { + for (FreezePeriod interval : sortedPeriods) { if (interval.after(nowDate)) { nextFreezeStart = interval.toCurrentOrFutureRealDates(nowDate).first; break; @@ -506,13 +508,13 @@ public class SystemUpdatePolicy implements Parcelable { /** @hide */ public void validateFreezePeriods() { - FreezeInterval.validatePeriods(mFreezePeriods); + FreezePeriod.validatePeriods(mFreezePeriods); } /** @hide */ public void validateAgainstPreviousFreezePeriod(LocalDate prevPeriodStart, LocalDate prevPeriodEnd, LocalDate now) { - FreezeInterval.validateAgainstPreviousFreezePeriod(mFreezePeriods, prevPeriodStart, + FreezePeriod.validateAgainstPreviousFreezePeriod(mFreezePeriods, prevPeriodStart, prevPeriodEnd, now); } @@ -521,10 +523,10 @@ public class SystemUpdatePolicy implements Parcelable { * updates and how long this action is valid for, given the current system update policy. Its * action could be one of the following * <ul> - * <li> {@code TYPE_INSTALL_AUTOMATIC} system updates should be installed immedately and without - * user intervention as soon as they become available. - * <li> {@code TYPE_POSTPONE} system updates should be postponed for a maximum of 30 days - * <li> {@code TYPE_PAUSE} system updates should be postponed indefinitely until further notice + * <li> {@link #TYPE_INSTALL_AUTOMATIC} system updates should be installed immedately and + * without user intervention as soon as they become available. + * <li> {@link #TYPE_POSTPONE} system updates should be postponed for a maximum of 30 days + * <li> {@link #TYPE_PAUSE} system updates should be postponed indefinitely until further notice * </ul> * * The effective time measures how long this installation option is valid for from the queried @@ -535,18 +537,38 @@ public class SystemUpdatePolicy implements Parcelable { */ @SystemApi public static class InstallationOption { + /** @hide */ + @IntDef(prefix = { "TYPE_" }, value = { + TYPE_INSTALL_AUTOMATIC, + TYPE_PAUSE, + TYPE_POSTPONE + }) + @Retention(RetentionPolicy.SOURCE) + @interface InstallationOptionType {} + + @InstallationOptionType private final int mType; private long mEffectiveTime; - InstallationOption(int type, long effectiveTime) { + InstallationOption(@InstallationOptionType int type, long effectiveTime) { this.mType = type; this.mEffectiveTime = effectiveTime; } - public int getType() { + /** + * Returns the type of the current installation option, could be one of + * {@link #TYPE_INSTALL_AUTOMATIC}, {@link #TYPE_POSTPONE} and {@link #TYPE_PAUSE}. + * @return type of installation option. + */ + public @InstallationOptionType int getType() { return mType; } + /** + * Returns how long the current installation option in effective for, starting from the time + * of query. + * @return the effective time in milliseconds. + */ public long getEffectiveTime() { return mEffectiveTime; } @@ -667,9 +689,11 @@ public class SystemUpdatePolicy implements Parcelable { int freezeCount = mFreezePeriods.size(); dest.writeInt(freezeCount); for (int i = 0; i < freezeCount; i++) { - FreezeInterval interval = mFreezePeriods.get(i); - dest.writeInt(interval.mStartDay); - dest.writeInt(interval.mEndDay); + FreezePeriod interval = mFreezePeriods.get(i); + dest.writeInt(interval.getStart().getMonthValue()); + dest.writeInt(interval.getStart().getDayOfMonth()); + dest.writeInt(interval.getEnd().getMonthValue()); + dest.writeInt(interval.getEnd().getDayOfMonth()); } } @@ -686,8 +710,9 @@ public class SystemUpdatePolicy implements Parcelable { int freezeCount = source.readInt(); policy.mFreezePeriods.ensureCapacity(freezeCount); for (int i = 0; i < freezeCount; i++) { - policy.mFreezePeriods.add( - new FreezeInterval(source.readInt(), source.readInt())); + MonthDay start = MonthDay.of(source.readInt(), source.readInt()); + MonthDay end = MonthDay.of(source.readInt(), source.readInt()); + policy.mFreezePeriods.add(new FreezePeriod(start, end)); } return policy; } @@ -730,9 +755,9 @@ public class SystemUpdatePolicy implements Parcelable { if (!parser.getName().equals(KEY_FREEZE_TAG)) { continue; } - policy.mFreezePeriods.add(new FreezeInterval( - Integer.parseInt(parser.getAttributeValue(null, KEY_FREEZE_START)), - Integer.parseInt(parser.getAttributeValue(null, KEY_FREEZE_END)))); + policy.mFreezePeriods.add(new FreezePeriod( + MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_START)), + MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_END)))); } return policy; } @@ -751,10 +776,10 @@ public class SystemUpdatePolicy implements Parcelable { out.attribute(null, KEY_INSTALL_WINDOW_START, Integer.toString(mMaintenanceWindowStart)); out.attribute(null, KEY_INSTALL_WINDOW_END, Integer.toString(mMaintenanceWindowEnd)); for (int i = 0; i < mFreezePeriods.size(); i++) { - FreezeInterval interval = mFreezePeriods.get(i); + FreezePeriod interval = mFreezePeriods.get(i); out.startTag(null, KEY_FREEZE_TAG); - out.attribute(null, KEY_FREEZE_START, Integer.toString(interval.mStartDay)); - out.attribute(null, KEY_FREEZE_END, Integer.toString(interval.mEndDay)); + out.attribute(null, KEY_FREEZE_START, interval.getStart().toString()); + out.attribute(null, KEY_FREEZE_END, interval.getEnd().toString()); out.endTag(null, KEY_FREEZE_TAG); } } diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java index 8f8083ed73e2..159e165d594f 100644 --- a/core/java/android/bluetooth/BluetoothHearingAid.java +++ b/core/java/android/bluetooth/BluetoothHearingAid.java @@ -421,29 +421,29 @@ public final class BluetoothHearingAid implements BluetoothProfile { } /** - * Check whether the device is active. + * Get the connected physical Hearing Aid devices that are active * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} * permission. * - * @return the connected device that is active or null if no device - * is active + * @return the list of active devices. The first element is the left active + * device; the second element is the right active device. If either or both side + * is not active, it will be null on that position. Returns empty list on error. * @hide */ @RequiresPermission(Manifest.permission.BLUETOOTH) - public boolean isActiveDevice(@Nullable BluetoothDevice device) { - if (VDBG) log("isActiveDevice()"); + public List<BluetoothDevice> getActiveDevices() { + if (VDBG) log("getActiveDevices()"); try { mServiceLock.readLock().lock(); - if (mService != null && isEnabled() - && ((device == null) || isValidDevice(device))) { - return mService.isActiveDevice(device); + if (mService != null && isEnabled()) { + return mService.getActiveDevices(); } if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return false; + return new ArrayList<>(); } catch (RemoteException e) { Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return false; + return new ArrayList<>(); } finally { mServiceLock.readLock().unlock(); } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 6748cdb0aeed..49b1efd08c91 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -1132,11 +1132,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int HIDDEN_API_ENFORCEMENT_NONE = 0; /** - * Light grey list enforcement, the strictest option. Enforces the light grey, dark grey and - * black lists. + * No API enforcement, but enable the detection logic and warnings. Observed behaviour is the + * same as {@link #HIDDEN_API_ENFORCEMENT_NONE} but you may see warnings in the log when APIs + * are accessed. * @hide * */ - public static final int HIDDEN_API_ENFORCEMENT_ALL_LISTS = 1; + public static final int HIDDEN_API_ENFORCEMENT_JUST_WARN = 1; /** * Dark grey list enforcement. Enforces the dark grey and black lists * @hide @@ -1158,7 +1159,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { @IntDef(prefix = { "HIDDEN_API_ENFORCEMENT_" }, value = { HIDDEN_API_ENFORCEMENT_DEFAULT, HIDDEN_API_ENFORCEMENT_NONE, - HIDDEN_API_ENFORCEMENT_ALL_LISTS, + HIDDEN_API_ENFORCEMENT_JUST_WARN, HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK, HIDDEN_API_ENFORCEMENT_BLACK, }) diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index b9dd376f464b..d1d5d8e460e8 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -467,7 +467,8 @@ public class ZygoteProcess { * <p>The list of exemptions will take affect for all new processes forked from the zygote after * this call. * - * @param exemptions List of hidden API exemption prefixes. + * @param exemptions List of hidden API exemption prefixes. Any matching members are treated as + * whitelisted/public APIs (i.e. allowed, no logging of usage). */ public void setApiBlacklistExemptions(List<String> exemptions) { synchronized (mLock) { diff --git a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java index 73a6a749d31c..9334aa99c86c 100644 --- a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java +++ b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java @@ -118,7 +118,7 @@ public final class KeyChainSnapshot implements Parcelable { * * See implementation for binary key format. * - * @removed Use {@link #getTrustedHardwareCertPath} instead. + * @deprecated Use {@link #getTrustedHardwareCertPath} instead. */ @Deprecated public @NonNull byte[] getTrustedHardwarePublicKey() { @@ -227,7 +227,7 @@ public final class KeyChainSnapshot implements Parcelable { * * @param publicKey The public key * @return This builder. - * @removed Use {@link #setTrustedHardwareCertPath} instead. + * @deprecated Use {@link #setTrustedHardwareCertPath} instead. */ @Deprecated public Builder setTrustedHardwarePublicKey(byte[] publicKey) { diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java index 2c48bf49b31b..f351c5afa579 100644 --- a/core/java/android/security/keystore/recovery/RecoveryController.java +++ b/core/java/android/security/keystore/recovery/RecoveryController.java @@ -288,7 +288,7 @@ public class RecoveryController { } /** - * @removed Use {@link #initRecoveryService(String, byte[], byte[])} instead. + * @deprecated Use {@link #initRecoveryService(String, byte[], byte[])} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @@ -359,7 +359,7 @@ public class RecoveryController { } /** - * @removed Use {@link #getKeyChainSnapshot()} + * @deprecated Use {@link #getKeyChainSnapshot()} */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @@ -435,7 +435,7 @@ public class RecoveryController { } /** - * @removed Use {@link #getAliases()}. + * @deprecated Use {@link #getAliases()}. */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @@ -460,7 +460,7 @@ public class RecoveryController { } /** - * @removed Use {@link #setRecoveryStatus(String, int)} + * @deprecated Use {@link #setRecoveryStatus(String, int)} */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @@ -494,7 +494,7 @@ public class RecoveryController { } /** - * @removed Use {@link #getRecoveryStatus(String)}. + * @deprecated Use {@link #getRecoveryStatus(String)}. */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @@ -576,7 +576,26 @@ public class RecoveryController { } /** - * @removed Use {@link #generateKey(String)}. + * Deprecated. + * Generates a AES256/GCM/NoPADDING key called {@code alias} and loads it into the recoverable + * key store. Returns the raw material of the key. + * + * @param alias The key alias. + * @param account The account associated with the key + * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery + * service. + * @throws LockScreenRequiredException if the user has not set a lock screen. This is required + * to generate recoverable keys, as the snapshots are encrypted using a key derived from the + * lock screen. + */ + @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) + public byte[] generateAndStoreKey(@NonNull String alias, byte[] account) + throws InternalRecoveryServiceException, LockScreenRequiredException { + throw new UnsupportedOperationException("Operation is not supported, use generateKey"); + } + + /** + * @deprecated Use {@link #generateKey(String)}. */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) diff --git a/core/java/android/security/keystore/recovery/RecoverySession.java b/core/java/android/security/keystore/recovery/RecoverySession.java index 87dc6b477eda..835338940905 100644 --- a/core/java/android/security/keystore/recovery/RecoverySession.java +++ b/core/java/android/security/keystore/recovery/RecoverySession.java @@ -78,7 +78,7 @@ public class RecoverySession implements AutoCloseable { } /** - * @removed Use {@link #start(String, CertPath, byte[], byte[], List)} instead. + * @deprecated Use {@link #start(String, CertPath, byte[], byte[], List)} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @@ -109,7 +109,7 @@ public class RecoverySession implements AutoCloseable { } /** - * @removed Use {@link #start(String, CertPath, byte[], byte[], List)} instead. + * @deprecated Use {@link #start(String, CertPath, byte[], byte[], List)} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @@ -198,7 +198,7 @@ public class RecoverySession implements AutoCloseable { } /** - * @removed Use {@link #recoverKeyChainSnapshot(byte[], List)} instead. + * @deprecated Use {@link #recoverKeyChainSnapshot(byte[], List)} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) diff --git a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java index 86419d8e4616..32952db7037d 100644 --- a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java +++ b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java @@ -75,7 +75,7 @@ public final class WrappedApplicationKey implements Parcelable { } /** - * @removed AOSP does not associate keys with accounts. This may be done by system app. + * @deprecated AOSP does not associate keys with accounts. This may be done by system app. */ @Deprecated public Builder setAccount(@NonNull byte[] account) { @@ -133,7 +133,7 @@ public final class WrappedApplicationKey implements Parcelable { } /** - * @removed AOSP does not associate keys with accounts. This may be done by system app. + * @deprecated AOSP does not associate keys with accounts. This may be done by system app. */ @Deprecated public @NonNull byte[] getAccount() { diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 3726e66d01f9..32737c54bea1 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -28,6 +28,7 @@ import android.app.Notification.Builder; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; +import android.app.Person; import android.app.Service; import android.companion.CompanionDeviceManager; import android.content.ComponentName; @@ -1195,13 +1196,13 @@ public abstract class NotificationListenerService extends Service { */ private void maybePopulatePeople(Notification notification) { if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P) { - ArrayList<Notification.Person> people = notification.extras.getParcelableArrayList( + ArrayList<Person> people = notification.extras.getParcelableArrayList( Notification.EXTRA_PEOPLE_LIST); if (people != null && people.isEmpty()) { int size = people.size(); String[] peopleArray = new String[size]; for (int i = 0; i < size; i++) { - Notification.Person person = people.get(i); + Person person = people.get(i); peopleArray[i] = person.resolveToLegacyUri(); } notification.extras.putStringArray(Notification.EXTRA_PEOPLE, peopleArray); diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java index 9c6a3f5f8c72..c905f49569d7 100644 --- a/core/java/android/text/util/Linkify.java +++ b/core/java/android/text/util/Linkify.java @@ -100,13 +100,20 @@ public class Linkify { * take an options mask. Note that this uses the * {@link android.webkit.WebView#findAddress(String) findAddress()} method in * {@link android.webkit.WebView} for finding addresses, which has various - * limitations. + * limitations and has been deprecated. + * @deprecated use {@link android.view.textclassifier.TextClassifier#generateLinks( + * TextLinks.Request)} instead and avoid it even when targeting API levels where no alternative + * is available. */ + @Deprecated public static final int MAP_ADDRESSES = 0x08; /** * Bit mask indicating that all available patterns should be matched in * methods that take an options mask + * <p><strong>Note:</strong></p> {@link #MAP_ADDRESSES} is deprecated. + * Use {@link android.view.textclassifier.TextClassifier#generateLinks(TextLinks.Request)} + * instead and avoid it even when targeting API levels where no alternative is available. */ public static final int ALL = WEB_URLS | EMAIL_ADDRESSES | PHONE_NUMBERS | MAP_ADDRESSES; diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index d4610a56332f..5deee11ba11e 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -87,6 +87,7 @@ public class SurfaceControl implements Parcelable { private static native void nativeMergeTransaction(long transactionObj, long otherTransactionObj); private static native void nativeSetAnimationTransaction(long transactionObj); + private static native void nativeSetEarlyWakeup(long transactionObj); private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder); private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject, @@ -1642,6 +1643,19 @@ public class SurfaceControl implements Parcelable { } /** + * Indicate that SurfaceFlinger should wake up earlier than usual as a result of this + * transaction. This should be used when the caller thinks that the scene is complex enough + * that it's likely to hit GL composition, and thus, SurfaceFlinger needs to more time in + * order not to miss frame deadlines. + * <p> + * Corresponds to setting ISurfaceComposer::eEarlyWakeup + */ + public Transaction setEarlyWakeup() { + nativeSetEarlyWakeup(mNativeObject); + return this; + } + + /** * Merge the other transaction into this transaction, clearing the * other transaction as if it had been applied. */ diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 5eb7e9cb2efe..e03f5faa26f2 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -190,6 +190,10 @@ public final class ThreadedRenderer { */ public static final String DEBUG_FPS_DIVISOR = "debug.hwui.fps_divisor"; + public static int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101; + public static int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102; + public static int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103; + static { // Try to check OpenGL support early if possible. isAvailable(); @@ -1140,6 +1144,16 @@ public final class ThreadedRenderer { nHackySetRTAnimationsEnabled(divisor <= 1); } + /** + * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be + * called before any OpenGL context is created. + * + * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values. + */ + public static void setContextPriority(int priority) { + nSetContextPriority(priority); + } + /** Not actually public - internal use only. This doc to make lint happy */ public static native void disableVsync(); @@ -1213,4 +1227,5 @@ public final class ThreadedRenderer { private static native void nHackySetRTAnimationsEnabled(boolean enabled); private static native void nSetDebuggingEnabled(boolean enabled); private static native void nSetIsolatedProcess(boolean enabled); + private static native void nSetContextPriority(int priority); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 97e11b157e7d..dc58f11e83fd 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -10398,7 +10398,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @param willNotCacheDrawing true if this view does not cache its * drawing, false otherwise + * + * @deprecated The view drawing cache was largely made obsolete with the introduction of + * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache + * layers are largely unnecessary and can easily result in a net loss in performance due to the + * cost of creating and updating the layer. In the rare cases where caching layers are useful, + * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware + * rendering. For software-rendered snapshots of a small part of the View hierarchy or + * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or + * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these + * software-rendered usages are discouraged and have compatibility issues with hardware-only + * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE} + * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback + * reports or unit testing the {@link PixelCopy} API is recommended. */ + @Deprecated public void setWillNotCacheDrawing(boolean willNotCacheDrawing) { setFlags(willNotCacheDrawing ? WILL_NOT_CACHE_DRAWING : 0, WILL_NOT_CACHE_DRAWING); } @@ -10407,8 +10421,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Returns whether or not this View can cache its drawing or not. * * @return true if this view does not cache its drawing, false otherwise + * + * @deprecated The view drawing cache was largely made obsolete with the introduction of + * hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache + * layers are largely unnecessary and can easily result in a net loss in performance due to the + * cost of creating and updating the layer. In the rare cases where caching layers are useful, + * such as for alpha animations, {@link #setLayerType(int, Paint)} handles this with hardware + * rendering. For software-rendered snapshots of a small part of the View hierarchy or + * individual Views it is recommended to create a {@link Canvas} from either a {@link Bitmap} or + * {@link android.graphics.Picture} and call {@link #draw(Canvas)} on the View. However these + * software-rendered usages are discouraged and have compatibility issues with hardware-only + * rendering features such as {@link android.graphics.Bitmap.Config#HARDWARE Config.HARDWARE} + * bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback + * reports or unit testing the {@link PixelCopy} API is recommended. */ @ViewDebug.ExportedProperty(category = "drawing") + @Deprecated public boolean willNotCacheDrawing() { return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING; } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index fc94b1f21fa1..10748acd4c51 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1837,8 +1837,12 @@ public class WebView extends AbsoluteLayout * * @param addr the string to search for addresses * @return the address, or if no address is found, {@code null} + * @deprecated this method is superseded by {@link TextClassifier#generateLinks( + * android.view.textclassifier.TextLinks.Request)}. Avoid using this method even when targeting + * API levels where no alternative is available. */ @Nullable + @Deprecated public static String findAddress(String addr) { if (addr == null) { throw new NullPointerException("addr is null"); @@ -2455,14 +2459,6 @@ public class WebView extends AbsoluteLayout return mWebViewThread; } - /** - * Returns the {@link Looper} corresponding to the thread on which WebView calls must be made. - */ - @NonNull - public Looper getLooper() { - return mWebViewThread; - } - //------------------------------------------------------------------------- // Interface for WebView providers //------------------------------------------------------------------------- diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index 4b951fa1824e..13729874d369 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -817,8 +817,6 @@ public class ImageView extends View { if (mScaleType != scaleType) { mScaleType = scaleType; - setWillNotCacheDrawing(mScaleType == ScaleType.CENTER); - requestLayout(); invalidate(); } diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index 53318c99ac34..d8a9ccad3f2e 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -408,6 +408,15 @@ public class TextClock extends TextView { } /** + * Update the displayed time if necessary and invalidate the view. + * @hide + */ + public void refresh() { + onTimeChanged(); + invalidate(); + } + + /** * Indicates whether the system is currently using the 24-hour mode. * * When the system is in 24-hour mode, this view will use the pattern diff --git a/core/java/com/android/internal/app/ColorDisplayController.java b/core/java/com/android/internal/app/ColorDisplayController.java index 278d31af7bde..f1539eeb1260 100644 --- a/core/java/com/android/internal/app/ColorDisplayController.java +++ b/core/java/com/android/internal/app/ColorDisplayController.java @@ -365,6 +365,10 @@ public final class ColorDisplayController { * Get the current color mode. */ public int getColorMode() { + if (getAccessibilityTransformActivated()) { + return COLOR_MODE_SATURATED; + } + final int colorMode = System.getIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, -1, mUserId); if (colorMode < COLOR_MODE_NATURAL || colorMode > COLOR_MODE_SATURATED) { @@ -416,6 +420,18 @@ public final class ColorDisplayController { R.integer.config_nightDisplayColorTemperatureDefault); } + /** + * Returns true if any Accessibility color transforms are enabled. + */ + public boolean getAccessibilityTransformActivated() { + final ContentResolver cr = mContext.getContentResolver(); + return + Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, + 0, mUserId) == 1 + || Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, + 0, mUserId) == 1; + } + private void onSettingChanged(@NonNull String setting) { if (DEBUG) { Slog.d(TAG, "onSettingChanged: " + setting); @@ -441,6 +457,10 @@ public final class ColorDisplayController { case System.DISPLAY_COLOR_MODE: mCallback.onDisplayColorModeChanged(getColorMode()); break; + case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED: + case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED: + mCallback.onAccessibilityTransformChanged(getAccessibilityTransformActivated()); + break; } } } @@ -471,6 +491,12 @@ public final class ColorDisplayController { false /* notifyForDescendants */, mContentObserver, mUserId); cr.registerContentObserver(System.getUriFor(System.DISPLAY_COLOR_MODE), false /* notifyForDecendants */, mContentObserver, mUserId); + cr.registerContentObserver( + Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED), + false /* notifyForDecendants */, mContentObserver, mUserId); + cr.registerContentObserver( + Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED), + false /* notifyForDecendants */, mContentObserver, mUserId); } } } @@ -531,5 +557,12 @@ public final class ColorDisplayController { * @param displayColorMode the color mode */ default void onDisplayColorModeChanged(int displayColorMode) {} + + /** + * Callback invoked when Accessibility color transforms change. + * + * @param state the state Accessibility color transforms (true of active) + */ + default void onAccessibilityTransformChanged(boolean state) {} } } diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index 1e5bd1894843..b49aaced83a3 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -657,7 +657,7 @@ public class BatteryStatsHelper { * {@link #removeHiddenBatterySippers(List)}. */ private void addAmbientDisplayUsage() { - long ambientDisplayMs = mStats.getScreenDozeTime(mRawRealtimeUs, mStatsType); + long ambientDisplayMs = mStats.getScreenDozeTime(mRawRealtimeUs, mStatsType) / 1000; double power = mPowerProfile.getAveragePower(PowerProfile.POWER_AMBIENT_DISPLAY) * ambientDisplayMs / (60 * 60 * 1000); if (power > 0) { diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java index f73b607b298b..07d78fe2abda 100644 --- a/core/java/com/android/internal/widget/MessagingGroup.java +++ b/core/java/com/android/internal/widget/MessagingGroup.java @@ -20,7 +20,7 @@ import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.app.Notification; +import android.app.Person; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; @@ -63,7 +63,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou private boolean mFirstLayout; private boolean mIsHidingAnimated; private boolean mNeedsGeneratedAvatar; - private Notification.Person mSender; + private Person mSender; private boolean mImagesAtEnd; private ViewGroup mImageContainer; private MessagingImageMessage mIsolatedMessage; @@ -126,7 +126,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou return position; } - public void setSender(Notification.Person sender, CharSequence nameOverride) { + public void setSender(Person sender, CharSequence nameOverride) { mSender = sender; if (nameOverride == null) { nameOverride = sender.getName(); @@ -466,7 +466,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou return mNeedsGeneratedAvatar; } - public Notification.Person getSender() { + public Person getSender() { return mSender; } diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java index 292df60bc259..f8236c78ac43 100644 --- a/core/java/com/android/internal/widget/MessagingLayout.java +++ b/core/java/com/android/internal/widget/MessagingLayout.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; import android.app.Notification; +import android.app.Person; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -79,7 +80,7 @@ public class MessagingLayout extends FrameLayout { private Icon mLargeIcon; private boolean mIsOneToOne; private ArrayList<MessagingGroup> mAddedGroups = new ArrayList<>(); - private Notification.Person mUser; + private Person mUser; private CharSequence mNameReplacement; private boolean mDisplayImagesAtEnd; @@ -160,7 +161,7 @@ public class MessagingLayout extends FrameLayout { for (int i = remoteInputHistory.length - 1; i >= 0; i--) { CharSequence message = remoteInputHistory[i]; newMessages.add(new Notification.MessagingStyle.Message( - message, 0, (Notification.Person) null)); + message, 0, (Person) null)); } } @@ -296,13 +297,13 @@ public class MessagingLayout extends FrameLayout { mIsOneToOne = oneToOne; } - public void setUser(Notification.Person user) { + public void setUser(Person user) { mUser = user; if (mUser.getIcon() == null) { Icon userIcon = Icon.createWithResource(getContext(), com.android.internal.R.drawable.messaging_user); userIcon.setTint(mLayoutColor); - mUser.setIcon(userIcon); + mUser = mUser.toBuilder().setIcon(userIcon).build(); } } @@ -310,7 +311,7 @@ public class MessagingLayout extends FrameLayout { List<MessagingMessage> messages) { // Let's first find our groups! List<List<MessagingMessage>> groups = new ArrayList<>(); - List<Notification.Person> senders = new ArrayList<>(); + List<Person> senders = new ArrayList<>(); // Lets first find the groups findGroups(historicMessages, messages, groups, senders); @@ -320,7 +321,7 @@ public class MessagingLayout extends FrameLayout { } private void createGroupViews(List<List<MessagingMessage>> groups, - List<Notification.Person> senders) { + List<Person> senders) { mGroups.clear(); for (int groupIndex = 0; groupIndex < groups.size(); groupIndex++) { List<MessagingMessage> group = groups.get(groupIndex); @@ -339,7 +340,7 @@ public class MessagingLayout extends FrameLayout { } newGroup.setDisplayImagesAtEnd(mDisplayImagesAtEnd); newGroup.setLayoutColor(mLayoutColor); - Notification.Person sender = senders.get(groupIndex); + Person sender = senders.get(groupIndex); CharSequence nameOverride = null; if (sender != mUser && mNameReplacement != null) { nameOverride = mNameReplacement; @@ -357,7 +358,7 @@ public class MessagingLayout extends FrameLayout { private void findGroups(List<MessagingMessage> historicMessages, List<MessagingMessage> messages, List<List<MessagingMessage>> groups, - List<Notification.Person> senders) { + List<Person> senders) { CharSequence currentSenderKey = null; List<MessagingMessage> currentGroup = null; int histSize = historicMessages.size(); @@ -369,7 +370,7 @@ public class MessagingLayout extends FrameLayout { message = messages.get(i - histSize); } boolean isNewGroup = currentGroup == null; - Notification.Person sender = message.getMessage().getSenderPerson(); + Person sender = message.getMessage().getSenderPerson(); CharSequence key = sender == null ? null : sender.getKey() == null ? sender.getName() : sender.getKey(); isNewGroup |= !TextUtils.equals(key, currentSenderKey); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index b0f68cde1486..3f58afa8d51e 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -327,6 +327,11 @@ static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz, jlong trans transaction->setAnimationTransaction(); } +static void nativeSetEarlyWakeup(JNIEnv* env, jclass clazz, jlong transactionObj) { + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); + transaction->setEarlyWakeup(); +} + static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jint zorder) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); @@ -934,6 +939,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeMergeTransaction }, {"nativeSetAnimationTransaction", "(J)V", (void*)nativeSetAnimationTransaction }, + {"nativeSetEarlyWakeup", "(J)V", + (void*)nativeSetEarlyWakeup }, {"nativeSetLayer", "(JJI)V", (void*)nativeSetLayer }, {"nativeSetRelativeLayer", "(JJLandroid/os/IBinder;I)V", diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 451f278313b5..7481f1c1fe53 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -992,6 +992,10 @@ static void android_view_ThreadedRenderer_setIsolatedProcess(JNIEnv*, jclass, jb Properties::isolatedProcess = isolated; } +static void android_view_ThreadedRenderer_setContextPriority(JNIEnv*, jclass, + jint contextPriority) { + Properties::contextPriority = contextPriority; +} // ---------------------------------------------------------------------------- // FrameMetricsObserver @@ -1103,6 +1107,7 @@ static const JNINativeMethod gMethods[] = { (void*)android_view_ThreadedRenderer_hackySetRTAnimationsEnabled }, { "nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled }, { "nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess }, + { "nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority }, }; static JavaVM* mJvm = nullptr; diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index 2a7c256031fe..ab15d4f701b7 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -118,17 +118,17 @@ message IncidentProto { // Stack dumps optional android.os.BackTraceProto native_traces = 1200 [ - (section).type = SECTION_NONE, + (section).type = SECTION_TOMBSTONE, (section).args = "native" ]; optional android.os.BackTraceProto hal_traces = 1201 [ - (section).type = SECTION_NONE, + (section).type = SECTION_TOMBSTONE, (section).args = "hal" ]; optional android.os.BackTraceProto java_traces = 1202 [ - (section).type = SECTION_NONE, + (section).type = SECTION_TOMBSTONE, (section).args = "java" ]; diff --git a/core/res/res/anim/activity_translucent_close_exit.xml b/core/res/res/anim/activity_translucent_close_exit.xml index 04c5dea07a79..02df0ff5052a 100644 --- a/core/res/res/anim/activity_translucent_close_exit.xml +++ b/core/res/res/anim/activity_translucent_close_exit.xml @@ -20,6 +20,6 @@ <translate android:fromYDelta="0%" android:toYDelta="100%" - android:interpolator="@interpolator/fast_out_linear_in" - android:duration="300"/> + android:interpolator="@interpolator/accelerate_quad" + android:duration="250"/> </set> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index ff262229e855..dc28e01b5307 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"কোনো ভইচ সেৱা নাই"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"ধ্বনি সেৱা বা জৰুৰীকালীন কলৰ সেৱা উপলব্ধ নহয়"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"আপোনাৰ বাহকে সাময়িকভাৱে অফ কৰি থৈছে"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"আপোনাৰ বাহকে <xliff:g id="SIMNUMBER">%d</xliff:g> ছিমৰ বাবে সাময়িকভাৱে অফ কৰিছে"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"ম\'বাইল নেটৱৰ্কৰ লগত সংযোগ কৰিব পৰা নাই"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"পচন্দৰ নেটৱৰ্ক সলনি কৰি চেষ্টা কৰি চাওক। সলনি কৰিবলৈ টিপক।"</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"জৰুৰীকালীন কল কৰাৰ সুবিধা উপলব্ধ নহয়"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"চিনাক্ত কৰিবপৰা নগ\'ল"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"ফিংগাৰপ্ৰিণ্টৰ সত্যাপন কৰা হ’ল"</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> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>এ অইন এপবোৰৰ ওপৰত প্ৰদৰ্শিত হৈ আছে"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"আপুনি যদি <xliff:g id="NAME">%s</xliff:g>এ এই সুবিধাটো ব্যৱহাৰ কৰাটো নিবিচাৰে তেন্তে টিপি ছেটিংসমূহ খোলক আৰু ইয়াক অফ কৰক।"</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"অফ কৰক"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> পৰীক্ষা কৰি থকা হৈছে…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"বৰ্তমানৰ সমলৰ সমীক্ষা কৰি থকা হৈছে"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"নতুন <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"ছেট আপ কৰিবলৈ টিপক"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ফট\' আৰু মিডিয়া স্থানান্তৰণৰ বাবে"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g>ত কিবা সমস্যা আছে"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"সমাধান কৰিবলৈ টিপক"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ব্যৱহাৰযোগ্য হৈ থকা নাই। ঠিক কৰিবলৈ বাছনি কৰক।"</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"ছেট আপ কৰক"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"বাহিৰ কৰক"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"অন্বেষণ কৰক"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> উপলব্ধ নহয়"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"পৰীক্ষা কৰি থকা হৈছে…"</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"ভইচৰ বাবে ছিমৰ প্ৰ\'ভিজন কৰা হোৱা নাই"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"ভইচৰ বাবে ছিম ব্যৱহাৰৰ অনুমতি নাই"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"ভইচৰ বাবে ফ\'ন ব্যৱহাৰৰ অনুমতি নাই"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"ছিম <xliff:g id="SIMNUMBER">%d</xliff:g> অনুমোদিত নহয়"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"ছিম <xliff:g id="SIMNUMBER">%d</xliff:g>ৰ প্ৰ\'ভিজন কৰা হোৱা নাই"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"ছিম <xliff:g id="SIMNUMBER">%d</xliff:g> অনুমোদিত নহয়"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"ছিম <xliff:g id="SIMNUMBER">%d</xliff:g> অনুমোদিত নহয়"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"পপআপ ৱিণ্ড\'"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"এপৰ সংস্কৰণ অৱনমিত কৰা হৈছে, বা ই এই শ্বৰ্টকাটটোৰ লগত খাপ নাখায়"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 78081388fc35..83bb71cbc898 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -84,7 +84,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Няма сэрвісу галасавых выклікаў"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"Галасавыя або экстранныя выклікі недаступныя"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"Часова выключана аператарам сувязі"</string> - <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Часова адключаны для SIM <xliff:g id="SIMNUMBER">%d</xliff:g> аператарам сувязі"</string> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Часова адключана для SIM <xliff:g id="SIMNUMBER">%d</xliff:g> аператарам сувязі"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"Сетка мабільнай сувязі недаступная"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Націсніце, каб выбраць іншую сетку."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Экстранныя выклікі недаступныя"</string> @@ -1321,7 +1321,7 @@ <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Знойдзена новая прылада: <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Дакраніцеся, каб наладзіць"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Для перадачы фатаграфій і медыяфайлаў"</string> - <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Праблема з носьбітам <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Праблема з носьбітам (<xliff:g id="NAME">%s</xliff:g>)"</string> <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Націсніце, каб выправіць"</string> <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"Носьбіт <xliff:g id="NAME">%s</xliff:g> пашкоджаны. Выберыце, каб выправіць."</string> <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> не падтрымліваецца"</string> @@ -1329,8 +1329,8 @@ <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_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_message" msgid="2110883356419799994">"Некаторыя функцыі могуць кепска працаваць. Устаўце новае сховішча."</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> <string name="ext_media_init_action" msgid="7952885510091978278">"Наладзіць"</string> @@ -1341,7 +1341,7 @@ <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_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> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 2b184a356949..198e67b45c57 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ভয়েস পরিষেবা নেই"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"ভয়েস পরিষেবা অথবা জরুরি কলের সুবিধা নেই"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"পরিষেবা প্রদানকারী এই সুবিধা সাময়িকভাবে বন্ধ রেখেছে"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"আপনার পরিষেবা প্রদানকারী <xliff:g id="SIMNUMBER">%d</xliff:g> সিমটি অস্থায়ীভাবে বন্ধ করেছে"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"মোবাইল নেটওয়ার্কে কানেক্ট করা যাচ্ছে না"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"পছন্দের নেটওয়ার্ক পরিবর্তন করে দেখুন। অন্য নেটওয়ার্ক বেছে নিতে ট্যাপ করুন।"</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"জরুরি কল করা যাবে না"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"স্বীকৃত নয়"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"আঙ্গুলের ছাপ যাচাই করা হয়েছে"</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> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> অন্যান্য অ্যাপের ওপর প্রদর্শিত হচ্ছে"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> কে এই বৈশিষ্ট্যটি ব্যবহার করতে দিতে না চাইলে, ট্যাপ করে সেটিংসে যান ও বৈশিষ্ট্যটি বন্ধ করে দিন।"</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"বন্ধ করুন"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> পরীক্ষা করা হচ্ছে…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"বর্তমান কন্টেন্টটি পর্যালোচনা করা হচ্ছে"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"নতুন <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"সেট-আপ করতে ট্যাপ করুন"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ফটো এবং মিডিয়া ট্রান্সফার"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> নিয়ে সমস্যা আছে"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"ঠিক করতে ট্যাপ করুন"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ত্রুটিপূর্ণ। মেরামত করতে বেছে নিন।"</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"সেট আপ করুন"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"বের করে নিন"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ঘুরে দেখুন"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> অনুপস্থিত"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"পরীক্ষা করা হচ্ছে..."</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"সিমটি ভয়েস কলের জন্য প্রস্তুত নয়"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"এই সিম দিয়ে ভয়েস কল করা যাবে না"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"এই ফোন দিয়ে ভয়েস কল করা যাবে না"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"<xliff:g id="SIMNUMBER">%d</xliff:g> সিমটি অনুমোদিত নয়"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"<xliff:g id="SIMNUMBER">%d</xliff:g> সিমটি প্রস্তুত নয়"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"<xliff:g id="SIMNUMBER">%d</xliff:g> সিমটি অনুমোদিত নয়"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"<xliff:g id="SIMNUMBER">%d</xliff:g> সিমটি অনুমোদিত নয়"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"পপ-আপ উইন্ডো"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>টি"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"অ্যাপের ভার্সন ডাউনগ্রেড করা হয়েছে অথবা এই শর্টকাটের জন্য উপযুক্ত নয়"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 81b3f35240fa..686e35e869f9 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -316,8 +316,8 @@ <string name="permdesc_statusBar" msgid="8434669549504290975">"Dozvoljava aplikaciji onemogućavanje statusne trake ili dodavanje i uklanjanje sistemskih ikona."</string> <string name="permlab_statusBarService" msgid="4826835508226139688">"funkcioniranje u vidu statusne trake"</string> <string name="permdesc_statusBarService" msgid="716113660795976060">"Dozvoljava aplikaciji da postane statusna traka."</string> - <string name="permlab_expandStatusBar" msgid="1148198785937489264">"otvaranje/zatvaranje statusne trake"</string> - <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Dozvoljava aplikaciji otvaranje ili zatvaranje statusne trake."</string> + <string name="permlab_expandStatusBar" msgid="1148198785937489264">"proširivanje/sužavanje statusne trake"</string> + <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Dozvoljava aplikaciji proširivanje ili sužavanje statusne trake."</string> <string name="permlab_install_shortcut" msgid="4279070216371564234">"instaliranje prečica"</string> <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Omogućava aplikaciji dodavanje prečice za početni ekran bez intervencije korisnika."</string> <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"uklanjanje prečica"</string> @@ -1767,7 +1767,7 @@ <string name="zen_mode_forever" msgid="931849471004038757">"Dok ne isključite"</string> <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dok ne isključite način rada Ne ometaj"</string> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> - <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skupi"</string> + <string name="toolbar_collapse_description" msgid="2821479483960330739">"Suzi"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne ometaj"</string> <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Prestanak rada"</string> <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Radni dan uvečer"</string> @@ -1787,7 +1787,7 @@ <string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Promijenjeno u novi SS zahtjev"</string> <string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil za posao"</string> <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Proširi"</string> - <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Skupi"</string> + <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Suzi"</string> <string name="expand_action_accessibility" msgid="5307730695723718254">"aktiviraj/deaktiviraj proširenje"</string> <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB ulaz za periferijske uređaje"</string> <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index ce52f1ba4ce5..2d1b37f19ed2 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sense servei de veu"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"No hi ha servei de veu ni trucades d\'emergència"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"L\'operador de telefonia mòbil ho ha desactivat temporalment"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"L\'operador de telefonia mòbil ho ha desactivat temporalment per a la SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"No es pot accedir a la xarxa mòbil"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Prova de canviar de xarxa preferida. Toca per canviar-la."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Les trucades d\'emergència no estan disponibles"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"No s\'ha reconegut"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"L\'empremta digital s\'ha autenticat"</string> <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"El maquinari per a empremtes digitals no està disponible."</string> <string name="fingerprint_error_no_space" msgid="1055819001126053318">"L\'empremta digital no es pot desar. Suprimeix-ne una."</string> <string name="fingerprint_error_timeout" msgid="3927186043737732875">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string> @@ -1274,49 +1272,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> s\'està superposant a altres apps"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Desactiva"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"S\'està comprovant el suport (<xliff:g id="NAME">%s</xliff:g>)…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"S\'està revisant el contingut actual"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Suport extern nou (<xliff:g id="NAME">%s</xliff:g>)"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Toca per configurar"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Per transferir fotos i fitxers multimèdia"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Problema amb el suport (<xliff:g id="NAME">%s</xliff:g>)"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Toca per solucionar el problema"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"La unitat següent està malmesa: <xliff:g id="NAME">%s</xliff:g>. Selecciona-la per solucionar-ho."</string> <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> no és compatible"</string> <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"El dispositiu no admet la unitat <xliff:g id="NAME">%s</xliff:g>. Toca per configurar-la amb un format compatible."</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Aquest dispositiu no admet la unitat següent: <xliff:g id="NAME">%s</xliff:g>. Selecciona-la per configurar-la en un format compatible."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"S\'ha extret <xliff:g id="NAME">%s</xliff:g> de manera inesperada"</string> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Expulsa el suport extern abans d\'extreure\'l per evitar perdre\'n el contingut"</string> + <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"S\'ha suprimit el suport (<xliff:g id="NAME">%s</xliff:g>)"</string> + <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Pot ser que algunes funcions no funcionin correctament. Insereix un altre dispositiu d\'emmagatzematge."</string> + <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"S\'està expulsant el suport (<xliff:g id="NAME">%s</xliff:g>)"</string> + <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"No extreguis el suport extern"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Configura"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Expulsa"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explora"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"No es detecta <xliff:g id="NAME">%s</xliff:g>"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <string name="ext_media_missing_message" msgid="4012389235250987930">"Torna a inserir el dispositiu"</string> <string name="ext_media_move_specific_title" msgid="1471100343872375842">"S\'està desplaçant l\'aplicació <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_move_title" msgid="1022809140035962662">"S\'estan desplaçant dades"</string> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <string name="ext_media_move_success_title" msgid="7863652232242276066">"S\'ha transferit el contingut"</string> + <string name="ext_media_move_success_message" msgid="8939137931961728009">"El contingut s\'ha transferit al suport extern (<xliff:g id="NAME">%s</xliff:g>)"</string> + <string name="ext_media_move_failure_title" msgid="1604422634177382092">"No s\'ha pogut transferir"</string> + <string name="ext_media_move_failure_message" msgid="7388950499623016135">"Torna a provar de transferir el contingut"</string> <string name="ext_media_status_removed" msgid="6576172423185918739">"S\'ha retirat"</string> <string name="ext_media_status_unmounted" msgid="2551560878416417752">"S\'ha expulsat"</string> <string name="ext_media_status_checking" msgid="6193921557423194949">"S\'està comprovant..."</string> @@ -1864,14 +1847,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"La SIM no està proporcionada per a la veu"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"La SIM no és compatible per a la veu"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"El telèfon no és compatible per a la veu"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"No s\'admet la SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"La SIM <xliff:g id="SIMNUMBER">%d</xliff:g> no s\'ha proporcionat"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"No s\'admet la SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"No s\'admet la SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Finestra emergent"</string> <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> més"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"S\'ha canviat a una versió anterior de l\'aplicació o la versió actual no és compatible amb aquesta drecera"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 38f8cde4c99f..deedfe5b3a87 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1284,7 +1284,7 @@ <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Denne enhed understøtter ikke dette <xliff:g id="NAME">%s</xliff:g>. Tryk for at konfigurere det til et understøttet format."</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Denne enhed understøtter ikke dette <xliff:g id="NAME">%s</xliff:g>. Vælg for at konfigurere mediet i et understøttet format."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> blev fjernet uventet"</string> - <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Skub mediet ud, inden du fjerner det, så du ikke mister dit indhold"</string> + <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Demonter mediet, inden du fjerner det, så du ikke mister dit indhold"</string> <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> er fjernet"</string> <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Nogle funktioner virker muligvis ikke som de skal. Indsæt en ny lagerenhed."</string> <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"Skubber <xliff:g id="NAME">%s</xliff:g> ud"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 0bb17ebc5c73..935f9e1c521e 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -82,7 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Keine Anrufe"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"Keine Anrufe oder Notrufe"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"Vorübergehend von deinem Mobilfunkanbieter deaktiviert"</string> - <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Vorübergehend von deinem Mobilfunkanbieter für SIM <xliff:g id="SIMNUMBER">%d</xliff:g> deaktiviert"</string> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Von deinem Mobilfunkanbieter für SIM <xliff:g id="SIMNUMBER">%d</xliff:g> vorübergehend deaktiviert"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"Mobilfunknetz nicht erreichbar"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Versuche, das bevorzugte Netzwerk zu ändern. Tippe, um ein anderes auszuwählen."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Notrufe nicht möglich"</string> @@ -1274,7 +1274,7 @@ <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Deaktivieren"</string> <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> wird geprüft…"</string> <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Aktuelle Inhalte werden geprüft"</string> - <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Neues Medium (<xliff:g id="NAME">%s</xliff:g>)"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Neues Speichergerät (<xliff:g id="NAME">%s</xliff:g>)"</string> <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Zum Einrichten tippen"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Zum Übertragen von Fotos und Medien"</string> <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Problem mit <xliff:g id="NAME">%s</xliff:g>"</string> @@ -1284,9 +1284,9 @@ <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"<xliff:g id="NAME">%s</xliff:g> wird von diesem Gerät nicht unterstützt. Zum Einrichten in einem unterstützten Format tippen."</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"<xliff:g id="NAME">%s</xliff:g> wird von diesem Gerät nicht unterstützt. Zur Einrichtung eines unterstützten Formats auswählen."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> wurde unerwartet entfernt"</string> - <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Trenne die Medien vor dem Entfernen, um Inhaltsverluste zu vermeiden"</string> + <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Lass das Speichergerät vor dem Entfernen auswerfen, damit keine Daten verloren gehen"</string> <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> wurde entfernt"</string> - <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Möglicherweise sind einige Funktionen fehlerhaft. Setze einen neuen Speicher ein."</string> + <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Einige Funktionen können möglicherweise nicht richtig genutzt werden. Sorge dafür, dass ein neues Speichergerät genutzt werden kann."</string> <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"<xliff:g id="NAME">%s</xliff:g> wird ausgeworfen"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Nicht entfernen"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Einrichten"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index e00e1751c1fa..462fd4b4329a 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -1013,10 +1013,8 @@ <string name="email_desc" msgid="3638665569546416795">"Email selected address"</string> <string name="dial" msgid="1253998302767701559">"Call"</string> <string name="dial_desc" msgid="6573723404985517250">"Call selected phone number"</string> - <!-- no translation found for map (5441053548030107189) --> - <skip /> - <!-- no translation found for map_desc (1836995341943772348) --> - <skip /> + <string name="map" msgid="5441053548030107189">"Map"</string> + <string name="map_desc" msgid="1836995341943772348">"Locate selected address"</string> <string name="browse" msgid="1245903488306147205">"Open"</string> <string name="browse_desc" msgid="8220976549618935044">"Open selected URL"</string> <string name="sms" msgid="4560537514610063430">"Message"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 510bcb307a02..27bfedfcbc81 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1287,7 +1287,7 @@ <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> ustekabean kendu da"</string> <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Kendu aurretik, kanporatu euskarria edukirik ez galtzeko"</string> <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"Kendu egin da <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Funtzio batzuk agian ez dira behar bezala ibiliko. Sartu memoria-gailu berria."</string> + <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Funtzio batzuek agian ez dute behar bezala funtzionatuko. Sartu biltegiratze-gailu berria."</string> <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"<xliff:g id="NAME">%s</xliff:g> kanporatzen"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Ez kendu"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Konfiguratu"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index cf0a7344572e..bffe248fbbd1 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -82,7 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Aucun service vocal"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"Aucun de service vocal ni d\'appel d\'urgence"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"Temporairement désactivé par votre fournisseur de services"</string> - <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Temporairement désactivé par votre fournisseur de services pour la carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Temporairement désactivé par votre fournisseur de services pour la carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"Impossible de joindre le réseau cellulaire"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Essayez de changer de réseau préféré. Touchez l\'écran pour changer."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Le service d\'appel d\'urgence n\'est pas accessible"</string> @@ -1274,7 +1274,7 @@ <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Désactiver"</string> <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"Vérification de <xliff:g id="NAME">%s</xliff:g> en cours…"</string> <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Vérification du contenu actuel"</string> - <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Nouveau/nouvelle <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Nouveau périphérique <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Toucher pour configurer"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Pour transférer des photos et d\'autres fichiers"</string> <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Il y a un problème avec <xliff:g id="NAME">%s</xliff:g>"</string> @@ -1298,7 +1298,7 @@ <string name="ext_media_move_title" msgid="1022809140035962662">"Déplacement des données..."</string> <string name="ext_media_move_success_title" msgid="7863652232242276066">"Transfert de contenu terminé"</string> <string name="ext_media_move_success_message" msgid="8939137931961728009">"Contenu déplacé vers <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="ext_media_move_failure_title" msgid="1604422634177382092">"Impossible de déplacer contenu"</string> + <string name="ext_media_move_failure_title" msgid="1604422634177382092">"Impossible de déplacer le contenu"</string> <string name="ext_media_move_failure_message" msgid="7388950499623016135">"Essayez de déplacer le contenu de nouveau"</string> <string name="ext_media_status_removed" msgid="6576172423185918739">"Supprimée"</string> <string name="ext_media_status_unmounted" msgid="2551560878416417752">"Éjectée"</string> @@ -1847,10 +1847,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"Cette carte SIM n\'est pas autorisée pour la voix"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"Cette carte SIM n\'est pas autorisée pour la voix"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"Ce téléphone n\'est pas autorisé pour la voix"</string> - <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string> - <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"Carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> non configurée"</string> - <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string> - <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas configurée"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Fenêtre contextuelle"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"La version de l\'application a été rétrogradée ou n\'est pas compatible avec ce raccourci"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 991e3ce489db..8a19b4f847d8 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1274,7 +1274,7 @@ <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Désactiver"</string> <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"Vérification de \"<xliff:g id="NAME">%s</xliff:g>\"…"</string> <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Vérification du contenu actuel"</string> - <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Nouvelle <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Nouveau périphérique : <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Appuyer pour configurer"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Pour transférer photos et fichiers"</string> <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Problème avec : <xliff:g id="NAME">%s</xliff:g>"</string> @@ -1284,16 +1284,16 @@ <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Cet appareil n\'est pas compatible avec la mémoire de stockage \"<xliff:g id="NAME">%s</xliff:g>\". Appuyez ici pour le configurer dans un format accepté."</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Cet appareil n\'est pas compatible avec cette <xliff:g id="NAME">%s</xliff:g>. Sélectionnez cette option pour la configurer dans un format accepté."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"Retrait inattendu de mémoire \"<xliff:g id="NAME">%s</xliff:g>\""</string> - <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Éjectez la mémoire de stockage externe avant de la retirer pour éviter toute perte de contenu"</string> - <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> supprimée"</string> - <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Certaines fonctionnalités risquent de ne pas s\'exécuter correctement. Insérez une nouvelle mémoire de stockage externe."</string> + <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Éjectez le périphérique externe avant de le retirer pour éviter toute perte de contenu"</string> + <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> supprimé"</string> + <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Certaines fonctionnalités risquent de ne pas s\'exécuter correctement. Insérez un nouveau périphérique de stockage externe."</string> <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"Éjection de \"<xliff:g id="NAME">%s</xliff:g>\""</string> - <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Ne retirez pas la mémoire de stockage"</string> + <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Ne retirez pas le périphérique"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Configurer"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Éjecter"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Parcourir"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"Mémoire de stockage \"<xliff:g id="NAME">%s</xliff:g>\" manquante"</string> - <string name="ext_media_missing_message" msgid="4012389235250987930">"Insérez de nouveau la mémoire"</string> + <string name="ext_media_missing_message" msgid="4012389235250987930">"Insérez le périphérique"</string> <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Transfert de l\'application <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_move_title" msgid="1022809140035962662">"Déplacement des données en cours"</string> <string name="ext_media_move_success_title" msgid="7863652232242276066">"Le contenu a bien été déplacé"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index b92d702c0b2e..8690318af4d0 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"કોઈ વૉઇસ સેવા નથી"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"કોઈ વૉઇસ સેવા અથવા કટોકટીની કૉલિંગ સેવા નથી"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"તમારા કૅરિઅરે હંગામી રૂપે બંધ કરી છે"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"તમારા કૅરિઅર દ્વારા સિમ <xliff:g id="SIMNUMBER">%d</xliff:g> માટે હંગામી રૂપે બંધ કરેલ છે"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"મોબાઇલ નેટવર્ક સુધી પહોંચી શકાતું નથી"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"પસંદગીનું નેટવર્ક બદલવાનો પ્રયાસ કરો. બદલવા માટે ટૅપ કરો."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"કટોકટીની કૉલિંગ સેવા અનુપલબ્ધ"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"ઓળખાયેલ નથી"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"ફિંગરપ્રિન્ટ પ્રમાણિત કરી"</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> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનો પર દેખાઈ છે"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"જો તમે નથી ઇચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ્સ ખોલવા માટે ટૅપ કરો અને તેને બંધ કરો."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"બંધ કરો"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> તપાસી રહ્યાં છીએ…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"હાલના કન્ટેન્ટને રિવ્યૂ કરવું"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"નવું <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"સેટ કરવા માટે ટૅપ કરો"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ફોટો અને મીડિયા ટ્રાન્સફર કરવા માટે"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g>ની સમસ્યા"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"ઠીક કરવા માટે ટૅપ કરો"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> દૂષિત છે. સુધારવા માટે પસંદ કરો."</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"સેટ કરો"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"બહાર કાઢો"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"અન્વેષણ કરો"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ખૂટે છે"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"તપાસી રહ્યું છે..."</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"આ સિમમાં વૉઇસ માટે કોઈ જોગવાઈ નથી"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"વૉઇસ માટે આ સિમને મંજૂરી નથી"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"વૉઇસ માટે આ ફોનને મંજૂરી નથી"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"સિમ <xliff:g id="SIMNUMBER">%d</xliff:g>ને મંજૂરી નથી"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"સિમ <xliff:g id="SIMNUMBER">%d</xliff:g>ની જોગવાઈ કરી નથી"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"સિમ <xliff:g id="SIMNUMBER">%d</xliff:g>ને મંજૂરી નથી"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"સિમ <xliff:g id="SIMNUMBER">%d</xliff:g>ને મંજૂરી નથી"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"પૉપઅપ વિંડો"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"આ ઍપનું વર્ઝન ડાઉનગ્રેડ કરવામાં આવ્યું છે અથવા આ શૉર્ટકટ સાથે સુસંગત નથી"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index e154a078c337..b0586fdd1901 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"कोई वॉइस सेवा नहीं है"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"सामान्य (वॉइस) कॉल या आपातकालीन कॉल पर रोक लगा दी गई है"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"आपकी मोबाइल और इंटरनेट सेवा देने वाली कंपनी ने सेवा पर कुछ समय के लिए रोक लगा दी है"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"सिम <xliff:g id="SIMNUMBER">%d</xliff:g> पर आपकी मोबाइल और इंटरनेट सेवा देने वाली कंपनी ने कुछ समय के लिए सेवा बंद कर दी है"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"मोबाइल नेटवर्क से कनेक्ट नहीं किया जा सका"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"पसंदीदा नेटवर्क बदलकर देखें. बदलने के लिए टैप करें."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"आपातकालीन कॉल करने की सुविधा उपलब्ध नहीं है"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"पहचाना नहीं गया"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"फ़िंगरप्रिंट की पुष्टि हो गई"</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> @@ -1021,7 +1019,7 @@ <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="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> @@ -1274,49 +1272,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप पर दिखाई दे रहा है"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने और उसे बंद करने के लिए टैप करें."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"बंद करें"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> ढूंढा जा रहा है…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"मौजूदा सामग्री की जाँच की जा रही है"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"नया <xliff:g id="NAME">%s</xliff:g> लगाया गया"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"सेटअप करने के लिए टैप करें"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"फ़ोटो और मीडिया ट्रांसफर करने के लिए"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> में गड़बड़ी है"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"समस्या ठीक करने के लिए टैप करें"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> काम नहीं कर रहा है. ठीक करने के लिए चुनें."</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"सेट करें"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"निकालें"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"एक्सप्लोर करें"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> गुम है"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"जाँच की जा रही है..."</string> @@ -1864,14 +1847,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"सिम से कॉल करने की इजाज़त नहीं है"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"सिम से कॉल करने की इजाज़त नहीं है"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"फ़ोन से कॉल करने की इजाज़त नहीं है"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"सिम <xliff:g id="SIMNUMBER">%d</xliff:g> को कॉल के लिए इस्तेमाल नहीं किया जा सकता"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"सिम <xliff:g id="SIMNUMBER">%d</xliff:g> काम नहीं कर रहा है"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"सिम <xliff:g id="SIMNUMBER">%d</xliff:g> को कॉल के लिए इस्तेमाल नहीं किया जा सकता"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"सिम <xliff:g id="SIMNUMBER">%d</xliff:g> को कॉल के लिए इस्तेमाल नहीं किया जा सकता"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"पॉपअप विंडो"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"ऐप्लिकेशन का वर्शन पुराना हो चुका है या यह इस शॉर्टकट के साथ काम नहीं करता"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 749dcba452b5..9a235d4ffc26 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Símtöl eru ekki í boði"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"Engin raddþjónusta eða neyðarsímtöl"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"Símafyrirtækið slökkti tímabundið á þessu"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Símafyrirtækið slökkti tímabundið á þessu fyrir SIM-kort <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"Ekki næst samband við farsímakerfi"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Prófaðu að velja annað símkerfi. Ýttu til að breyta."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Neyðarsímtöl eru ekki í boði"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Þekktist ekki"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"Fingrafar staðfest"</string> <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingrafarsvélbúnaður ekki til staðar."</string> <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Ekki er hægt að vista fingrafarið. Fjarlægðu eitthvert af fingraförunum sem fyrir eru."</string> <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tímamörk runnu út fyrir fingrafar. Reyndu aftur."</string> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> birtist yfir öðrum forritum"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ef þú vilt ekki að <xliff:g id="NAME">%s</xliff:g> noti þennan eiginleika skaltu ýta til að opna stillingarnar og slökkva á því."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Slökkva"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"Athugar <xliff:g id="NAME">%s</xliff:g>…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Fer yfir núverandi efni"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Nýtt <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Ýttu til að setja upp"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Til að flytja myndir og aðrar skrár"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Vandamál með <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Ýttu til að lagfæra"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> er skemmt. Veldu til að lagfæra."</string> <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"Óstutt <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Þetta tæki styður ekki <xliff:g id="NAME">%s</xliff:g>. Ýttu til að setja upp með studdu sniði."</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Þetta tæki styður ekki <xliff:g id="NAME">%s</xliff:g>. Veldu til að setja upp með studdu sniði."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> fjarlægt án fyrirvara"</string> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Aftengdu geymslumiðil áður en þú tekur hann úr sambandi til að koma í veg fyrir að þú glatir efni"</string> + <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> fjarlægt"</string> + <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Ekki er víst að allt virki eðlilega. Tengdu nýjan geymslumiðil."</string> + <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"Aftengir <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Ekki fjarlægja"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Setja upp"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Fjarlægja"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Kanna"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> vantar"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <string name="ext_media_missing_message" msgid="4012389235250987930">"Tengdu tækið aftur"</string> <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Flytur <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_move_title" msgid="1022809140035962662">"Flytur gögn"</string> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <string name="ext_media_move_success_title" msgid="7863652232242276066">"Efni hefur verið flutt"</string> + <string name="ext_media_move_success_message" msgid="8939137931961728009">"Efni flutt yfir í <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="1604422634177382092">"Ekki var hægt að flytja efni"</string> + <string name="ext_media_move_failure_message" msgid="7388950499623016135">"Reyndu að flytja efni aftur"</string> <string name="ext_media_status_removed" msgid="6576172423185918739">"Fjarlægð"</string> <string name="ext_media_status_unmounted" msgid="2551560878416417752">"Aftengd"</string> <string name="ext_media_status_checking" msgid="6193921557423194949">"Athugar…"</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM-korti er ekki úthlutað fyrir rödd"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM-kort er ekki heimilað fyrir rödd"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"Sími er ekki heimilaður fyrir rödd"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"SIM-kort <xliff:g id="SIMNUMBER">%d</xliff:g> er ekki leyft"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> hefur ekki verið úthlutað"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"SIM-kort <xliff:g id="SIMNUMBER">%d</xliff:g> er ekki leyft"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"SIM-kort <xliff:g id="SIMNUMBER">%d</xliff:g> er ekki leyft"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Sprettigluggi"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"Útgáfa forritsins er of gömul eða er ekki samhæf þessari flýtileið"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index fafde5c7ea02..dcec07441696 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -272,31 +272,31 @@ <string name="managed_profile_label" msgid="8947929265267690522">"Passa a profilo di lavoro"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatti"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accedere ai contatti"</string> - <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere ai tuoi contatti?"</string> + <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere ai tuoi contatti?"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Geolocalizzazione"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"accedere alla posizione di questo dispositivo"</string> - <string name="permgrouprequest_location" msgid="3788275734953323491">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione di questo dispositivo?"</string> + <string name="permgrouprequest_location" msgid="3788275734953323491">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione di questo dispositivo?"</string> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedere al calendario"</string> - <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere al tuo calendario?"</string> + <string name="permgrouprequest_calendar" msgid="289900767793189421">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere al tuo calendario?"</string> <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string> <string name="permgroupdesc_sms" msgid="4656988620100940350">"inviare e visualizzare SMS"</string> - <string name="permgrouprequest_sms" msgid="7168124215838204719">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di inviare e visualizzare SMS?"</string> + <string name="permgrouprequest_sms" msgid="7168124215838204719">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di inviare e visualizzare SMS?"</string> <string name="permgrouplab_storage" msgid="1971118770546336966">"Archiviazione"</string> <string name="permgroupdesc_storage" msgid="637758554581589203">"accedere a foto, contenuti multimediali e file sul dispositivo"</string> - <string name="permgrouprequest_storage" msgid="7885942926944299560">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere a foto, contenuti multimediali e file memorizzati sul dispositivo?"</string> + <string name="permgrouprequest_storage" msgid="7885942926944299560">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere a foto, contenuti multimediali e file memorizzati sul dispositivo?"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfono"</string> <string name="permgroupdesc_microphone" msgid="4988812113943554584">"registrare audio"</string> - <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di registrare audio?"</string> + <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di registrare audio?"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"Fotocamera"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"scattare foto e registrare video"</string> - <string name="permgrouprequest_camera" msgid="1299833592069671756">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di scattare foto e registrare video?"</string> + <string name="permgrouprequest_camera" msgid="1299833592069671756">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di scattare foto e registrare video?"</string> <string name="permgrouplab_phone" msgid="5229115638567440675">"Telefono"</string> <string name="permgroupdesc_phone" msgid="6234224354060641055">"eseguire e gestire le telefonate"</string> - <string name="permgrouprequest_phone" msgid="9166979577750581037">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di effettuare e gestire telefonate?"</string> + <string name="permgrouprequest_phone" msgid="9166979577750581037">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di effettuare e gestire telefonate?"</string> <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensori per il corpo"</string> <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accedere ai dati dei sensori relativi ai tuoi parametri vitali"</string> - <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Vuoi consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere ai dati dei sensori relativi ai parametri vitali?"</string> + <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere ai dati dei sensori relativi ai parametri vitali?"</string> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperare contenuti della finestra"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Esaminare i contenuti di una finestra con cui interagisci."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Attivare Esplora al tocco"</string> @@ -1272,12 +1272,12 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"App <xliff:g id="NAME">%s</xliff:g> mostrata sopra altre app"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"Se non desideri che l\'app <xliff:g id="NAME">%s</xliff:g> utilizzi questa funzione, tocca per aprire le impostazioni e disattivarla."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Disattiva"</string> - <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"Controllo della <xliff:g id="NAME">%s</xliff:g>…"</string> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"Controllo del dispositivo <xliff:g id="NAME">%s</xliff:g>…"</string> <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Controllo dei contenuti correnti"</string> - <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Nuova <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Nuovo dispositivo <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Tocca per configurare"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Per trasferire foto e altri file"</string> - <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Problema con la <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Problema con <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Tocca per risolvere il problema"</string> <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"Il supporto esterno <xliff:g id="NAME">%s</xliff:g> è danneggiato. Seleziona per risolvere il problema."</string> <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> non supportata"</string> @@ -1285,19 +1285,19 @@ <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Il dispositivo non supporta questo tipo di <xliff:g id="NAME">%s</xliff:g>. Seleziona per eseguire la configurazione in un formato supportato."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"Rimozione imprevista della <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Espelli il supporto prima di rimuoverlo per evitare di perdere contenuti"</string> - <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> rimossa"</string> + <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"Dispositivo <xliff:g id="NAME">%s</xliff:g> rimosso"</string> <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Alcune funzionalità potrebbero non funzionare correttamente. Inserisci un nuovo supporto di archiviazione."</string> - <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"Espulsione della <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"Espulsione di <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Non rimuovere"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Configura"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Espelli"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Apri"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> mancante"</string> - <string name="ext_media_missing_message" msgid="4012389235250987930">"Inserisci di nuovo dispositivo"</string> + <string name="ext_media_missing_message" msgid="4012389235250987930">"Reinserisci il dispositivo"</string> <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Spostamento di <xliff:g id="NAME">%s</xliff:g> in corso"</string> <string name="ext_media_move_title" msgid="1022809140035962662">"Spostamento dei dati in corso"</string> <string name="ext_media_move_success_title" msgid="7863652232242276066">"Trasferimento contenuti completo"</string> - <string name="ext_media_move_success_message" msgid="8939137931961728009">"Contenuti spostati sulla <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_success_message" msgid="8939137931961728009">"Contenuti spostati su <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_move_failure_title" msgid="1604422634177382092">"Impossibile spostare i contenuti"</string> <string name="ext_media_move_failure_message" msgid="7388950499623016135">"Riprova a spostare i contenuti"</string> <string name="ext_media_status_removed" msgid="6576172423185918739">"Rimosso"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index f6d4e3ab9b88..6f7d40e003b9 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1284,7 +1284,7 @@ <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_message" msgid="8556885808951260574">"コンテンツを消去しないようメディアを取り出してから取り外してください"</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_message" msgid="2110883356419799994">"一部の機能が正しく動作しない可能性があります。新しいストレージを挿入してください。"</string> <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"<xliff:g id="NAME">%s</xliff:g>を取り出しています"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 5f4a4e6144da..0cf43e296bf2 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1278,17 +1278,17 @@ <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Жаңа <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Реттеу үшін түртіңіз"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Фотосуреттер мен медиа файлдарын тасымалдау үшін"</string> - <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> арқылы шығарыңыз"</string> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> ақаулы"</string> <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Түзету үшін түртіңіз"</string> <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> бүлінген. Түзету үшін оны түртіңіз."</string> <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_message" msgid="8556885808951260574">"Мазмұнды жоғалтып алмау үшін ақпарат тасығышты алдымен шығарыңыз, одан кейін алыңыз."</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_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_title" msgid="5046532339291216076">"<xliff:g id="NAME">%s</xliff:g> ажыратылуда"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Шығармаңыз"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Реттеу"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Шығару"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index f2af6e5f45ae..457db545b275 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1285,9 +1285,9 @@ <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_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_title" msgid="5046532339291216076">"<xliff:g id="NAME">%s</xliff:g> 마운트 해제 중"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"외부 미디어를 제거하지 마세요."</string> <string name="ext_media_init_action" msgid="7952885510091978278">"설정"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"마운트 해제"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 8d4d20b33dc9..c1fb9f88952e 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -82,7 +82,7 @@ <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> SIM-картасы үчүн байланыш оператору тарабынан убактылуу бөгөттөлгөн"</string> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> үчүн байланыш оператору тарабынан убактылуу бөгөттөлгөн"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"Мобилдик тармакка туташпай жатат"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Тандалган тармакты өзгөртүп көрүңүз. Өзгөртүү үчүн таптаңыз."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Шашылыш чалуу жеткиликсиз"</string> @@ -1286,10 +1286,10 @@ <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_message" msgid="8556885808951260574">"Мазмунду жоготуунун алдын алуу үчүн алып салуудан мурда медианы чыгарыңыз"</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_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_title" msgid="5046532339291216076">"<xliff:g id="NAME">%s</xliff:g> өчүрүлүүдө"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Чыгарбаңыз"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Орнотуу"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Чыгаруу"</string> @@ -1299,7 +1299,7 @@ <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> SD-картасына жылдырылды"</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> @@ -1849,10 +1849,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM-карта сүйлөшүү үчүн таанылган жок"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM-картаны сүйлөшүү үчүн колдонууга тыюу салынган"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"Телефонду сүйлөшүү үчүн колдонууга тыюу салынган"</string> - <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"<xliff:g id="SIMNUMBER">%d</xliff:g> номериндеги SIM-картасына уруксат берилген жок"</string> - <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"<xliff:g id="SIMNUMBER">%d</xliff:g> номериндеги SIM-карта таанылган жок"</string> - <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"<xliff:g id="SIMNUMBER">%d</xliff:g> номериндеги SIM-картасына уруксат берилген жок"</string> - <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"<xliff:g id="SIMNUMBER">%d</xliff:g> номериндеги SIM-картасына уруксат берилген жок"</string> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> картасына уруксат берилген жок"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> картасы таанылган жок"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> картасына уруксат берилген жок"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> картасына уруксат берилген жок"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Калкып чыкма терезе"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"Колдонмонун мурунку версиясын иштетип жатасыз же ал бул шилтемеге шайкеш эмес"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 4fa37f95a08b..de6d37b4f976 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1285,10 +1285,10 @@ <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_message" msgid="8556885808951260574">"Откачете ја надворешната меморија пред да ја отстраните за да избегнете губење содржини"</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_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_title" msgid="5046532339291216076">"Се исклучува <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Не отстранувајте"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Постави"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Извади"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index ad39d8f39c59..62061f1dc111 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1300,7 +1300,7 @@ <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_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_checking" msgid="6193921557423194949">"പരിശോധിക്കുന്നു…"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 18c665dce0fd..dff7e8bbf692 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1273,22 +1273,22 @@ <string name="alert_windows_notification_message" msgid="8917232109522912560">"Та <xliff:g id="NAME">%s</xliff:g>-д энэ онцлогийг ашиглахыг хүсэхгүй байгаа бол тохиргоог нээгээд, унтраана уу."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Унтраах"</string> <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g>-г шалгаж байна…"</string> - <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Одоогийн агуулгыг харж байна"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Одоогийн агуулгыг хянаж байна"</string> <string name="ext_media_new_notification_title" msgid="1621805083736634077">"Шинэ <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Тохируулахын тулд товшино уу"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Зураг, медиа шилжүүлэхэд зориулсан"</string> - <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g>-р олгоно уу"</string> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> алдаатай байна"</string> <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Засахын тулд товшино уу"</string> <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> эвдэрсэн байна. Засахын тулд сонгоно уу."</string> <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_message" msgid="8556885808951260574">"Агуулга алдахаас сэргийлэхийн тулд медиаг устгахаасаа өмнө салгана уу"</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_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> + <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Бүү салга"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Тохируулах"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Салгах"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Судлах"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index aa54aca48f01..7ebb08717d25 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"व्हॉइस सेवा नाही"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"व्हॉइस सेवा किंवा आणीबाणी कॉलिंग नाही"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"तुमच्या वाहकाने तात्पुरते बंद केले आहे"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"<xliff:g id="SIMNUMBER">%d</xliff:g> सिमसाठी तुमच्या वाहकाने तात्पुरते बंद केले आहे"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"मोबाइल नेटवर्क उपलब्ध नाही"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"प्राधान्य दिलेले नेटवर्क बदलण्याचा प्रयत्न करा. बदलण्यासाठी टॅप करा."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"आणीबाणी कॉलिंग अनुपलब्ध"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"ओळखले नाही"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"फिंगरप्रिंट ऑथेंटिकेट केली आहे"</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> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> अन्य अॅप्सवर प्रदर्शित करत आहे"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ने हे वैशिष्ट्य वापरू नये असे आपण इच्छित असल्यास, सेटिंग्ज उघडण्यासाठी टॅप करा आणि ते बंद करा."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"बंद करा"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> तपासत आहे…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"सध्याच्या आशयाचे पुनरावलोकन करत आहे"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"नवीन <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"सेट करण्यासाठी टॅप करा"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"फोटो आणि मीडिया स्थानांतरित करण्यासाठी"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> सह समस्या"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"दुरुस्त करण्यासाठी टॅप करा"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> दूषित आहे. निश्चित करण्यासाठी निवडा."</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"सेट करा"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"बाहेर काढा"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"एक्सप्लोर करा"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> गहाळ आहे"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"तपासत आहे..."</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"सिममध्ये व्हॉइसची तरतूद नाही"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"व्हॉइसची सिमला अनुमती नाही"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"व्हॉइसची फोनला अनुमती नाही"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"<xliff:g id="SIMNUMBER">%d</xliff:g> सिमला अनुमती नाही"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"<xliff:g id="SIMNUMBER">%d</xliff:g> सिमची तरतूद केलेली नाही"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"<xliff:g id="SIMNUMBER">%d</xliff:g> सिमला अनुमती नाही"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"<xliff:g id="SIMNUMBER">%d</xliff:g> सिमला अनुमती नाही"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"पॉपअप विंडो"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"अॅपची आवृत्ती डाउनग्रेड केली, किंवा ती या शॉर्टकटशी कंपॅटिबल नाही"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index e802f0ca1ab0..5a30d2e74fe2 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -497,7 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"အသိအမှတ်မပြုပါ"</string> - <string name="fingerprint_authenticated" msgid="5309333983002526448">"လက်ဗွေကို အထောက်အထားစိစစ်ပြီးပါပြီ"</string> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"လက်ဗွေကို အထောက်အထား စိစစ်ပြီးပါပြီ"</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> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index ddd411163549..3f64397e98ff 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -287,7 +287,7 @@ <string name="permgrouprequest_storage" msgid="7885942926944299560">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot foto\'s, media en bestanden op je apparaat?"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfoon"</string> <string name="permgroupdesc_microphone" msgid="4988812113943554584">"audio opnemen"</string> - <string name="permgrouprequest_microphone" msgid="9167492350681916038">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om audio op te nemen?"</string> + <string name="permgrouprequest_microphone" msgid="9167492350681916038">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> het volgende toestaan: audio opnemen."</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"foto\'s maken en video opnemen"</string> <string name="permgrouprequest_camera" msgid="1299833592069671756">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om foto\'s te maken en video op te nemen?"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index b660c202b14f..b341cf41fdab 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"କୌଣସି ଭଏସ୍ ସେବା ନାହିଁ"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"କୌଣସି ଭଏସ୍ ସେବା କିମ୍ବା ଜରୁରୀକାଳୀନ କଲିଙ୍ଗ ନାହିଁ"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"ଆପଣଙ୍କ କେରିଅର୍ଙ୍କ ଦ୍ୱାରା ଅସ୍ଥାୟୀ ରୂପେ ବନ୍ଦ କରାଯାଇଛି"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> ପାଇଁ ଆପଣଙ୍କ କେରିଅର୍ ଦ୍ୱାରା ଅସ୍ଥାୟୀ ରୂପେ ବନ୍ଦ କରାଯାଇଛି"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"ମୋବାଇଲ୍ ନେଟ୍ୱର୍କ ମିଳୁନାହିଁ"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"ନିଜ ପସନ୍ଦର ନେଟ୍ୱର୍କକୁ ଯିବାପାଇଁ ଚେଷ୍ଟା କରନ୍ତୁ। ବଦଳାଇବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"ଜରୁରୀକାଳୀନ କଲ୍ ଉପଲବ୍ଧ ନାହିଁ"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"ଚିହ୍ନଟ ହେଲା ନାହିଁ"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ପ୍ରମାଣୀକୃତ ହେଲା"</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> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ଅନ୍ୟ ଆପ୍ ଉପରେ ଦେଖାଯାଉଛି"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"ଏହି ବୈଶିଷ୍ଟ୍ୟ <xliff:g id="NAME">%s</xliff:g> ବ୍ୟବହାର ନକରିବାକୁ ଯଦି ଆପଣ ଚାହାଁନ୍ତି, ସେଟିଙ୍ଗ ଖୋଲିବାକୁ ଟାପ୍ କରନ୍ତୁ ଏବଂ ଏହା ଅଫ୍ କରିଦିଅନ୍ତୁ।"</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ବନ୍ଦ କରନ୍ତୁ"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g>ର ଯାଞ୍ଚ କରାଯାଉଛି…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"ସାମ୍ପ୍ରତିକ କଣ୍ଟେଣ୍ଟର ଯାଞ୍ଚ କରାଯାଉଛି"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"ନୂଆ <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"ସେଟଅପ୍ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ଫଟୋ ଓ ମିଡିଆ ସ୍ଥାନାନ୍ତର କରାଯିବା ପାଇଁ"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> ସହ ସମସ୍ୟା"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"ଠିକ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ଖରାପ ହୋଇଯାଇଛି। ଠିକ୍ କରିବାକୁ ଚୟନ କରନ୍ତୁ।"</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ବାହାର କରନ୍ତୁ"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ଖୋଜନ୍ତୁ"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ନାହିଁ"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"ଯାଞ୍ଚ କରାଯାଉଛି…"</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM କାର୍ଡକୁ ଭଏସ୍ ପାଇଁ ପ୍ରସ୍ତୁତ କରାଯାଇନାହିଁ"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM କାର୍ଡକୁ ଭଏସ୍ ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"ଫୋନକୁ ଭଏସ୍ ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g>ର ଅନୁମତି ନାହିଁ"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g>ର ପ୍ରାବଧାନ ନାହିଁ"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g>ର ଅନୁମତି ନାହିଁ"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g>ର ଅନୁମତି ନାହିଁ"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"ପପ-ଅପ୍ ୱିଣ୍ଡୋ"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"ଆପ୍ ଭର୍ସନ୍ ପୁରୁଣା ହୋଇଯାଇଛି କିମ୍ବା ଏହି ଶର୍ଟକଟ୍ ସହିତ କାମ କରୁନାହିଁ।"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 6e429a56f29f..568b2376cb4b 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ਕੋਈ ਆਵਾਜ਼ੀ ਸੇਵਾ ਨਹੀਂ"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"ਕੋਈ ਅਵਾਜ਼ੀ ਸੇਵਾ ਜਾਂ ਸੰਕਟਕਾਲੀਨ ਕਾਲਿੰਗ ਨਹੀਂ"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਹੈ"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"ਸਿਮ <xliff:g id="SIMNUMBER">%d</xliff:g> ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਹੈ"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਨੂੰ ਬਦਲ ਕੇ ਦੇਖੋ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਿੰਗ ਉਪਲਬਧ ਨਹੀਂ"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</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> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ਐਪ ਹੋਰਾਂ ਐਪਾਂ ਦੇ ਉੱਤੇ ਹੈ।"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"ਜੇਕਰ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ਬੰਦ ਕਰੋ"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> ਦੀ ਜਾਂਚ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"ਵਰਤਮਾਨ ਸਮੱਗਰੀ ਦੀ ਸਮੀਖਿਆ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"ਨਵਾਂ <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ ਨੂੰ ਟ੍ਰਾਂਸਫ਼ਰ ਕਰਨ ਲਈ"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"ਠੀਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ਖਰਾਬ ਹੈ। ਠੀਕ ਕਰਨ ਲਈ ਚੁਣੋ।"</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"ਸਥਾਪਤ ਕਰੋ"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ਬਾਹਰ ਕੱਢੋ"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ਐਕਸਪਲੋਰ ਕਰੋ"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ਲਾਪਤਾ"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"ਜਾਂਚ ਕਰ ਰਿਹਾ ਹੈ..."</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"ਸਿਮ ਰਾਹੀਂ ਅਵਾਜ਼ੀ ਕਾਲ ਕਰਨ ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"ਸਿਮ ਰਾਹੀਂ ਅਵਾਜ਼ੀ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"ਫ਼ੋਨ ਰਾਹੀਂ ਅਵਾਜ਼ੀ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"ਸਿਮ <xliff:g id="SIMNUMBER">%d</xliff:g> ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"ਸਿਮ <xliff:g id="SIMNUMBER">%d</xliff:g> ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"ਸਿਮ <xliff:g id="SIMNUMBER">%d</xliff:g> ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"ਸਿਮ <xliff:g id="SIMNUMBER">%d</xliff:g> ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"ਪੌਪਅੱਪ ਵਿੰਡੋ"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"ਐਪ ਦਾ ਵਰਜਨ ਡਾਊਨਗ੍ਰੇਡ ਕੀਤਾ ਗਿਆ, ਜਾਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਦੇ ਅਨੁਕੂਲ ਨਹੀਂ ਹੈ"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index b6e2e57a1c38..784d31614e37 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1286,7 +1286,7 @@ <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> foi removido inesperadamente"</string> <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Ejete o armazenamento multimédia antes de o remover para evitar a perda de conteúdos."</string> <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"<xliff:g id="NAME">%s</xliff:g> removido"</string> - <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Algumas funcionalidades podem não funcionar corretamente. Insira um novo armazenamento."</string> + <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Algumas funcionalidades podem não funcionar corretamente. Insira um novo dispositivo de armazenamento."</string> <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"A ejetar <xliff:g id="NAME">%s</xliff:g>…"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Não remova."</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Configurar"</string> @@ -1848,7 +1848,7 @@ <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM não permitido para voz"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"Telemóvel não permitido para voz"</string> <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> não autorizado"</string> - <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> não aprovisionado"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> não fornecido"</string> <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> não autorizado"</string> <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> não autorizado"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Janela pop-up"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 34e1c82fe5ab..3aa5d2560c91 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1306,10 +1306,10 @@ <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Dispozitivul nu este compatibil cu acest <xliff:g id="NAME">%s</xliff:g>. Atingeți pentru configurare într-un format compatibil."</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Dispozitivul nu este compatibil cu acest <xliff:g id="NAME">%s</xliff:g>. Selectați pentru configurare într-un format compatibil."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> scos pe neașteptate"</string> - <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Îndepărtați dispozitivele media înainte de a le elimina pentru a evita pierderea conținutului"</string> + <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Deconectați din setări dispozitivele media înainte de a le îndepărta, pentru a evita pierderea conținutului"</string> <string name="ext_media_nomedia_notification_title" msgid="6593814191061956856">"S-a eliminat <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Este posibil ca unele funcții să nu funcționeze corespunzător. Introduceți un spațiu de stocare nou."</string> - <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"Se scoate <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_nomedia_notification_message" msgid="2110883356419799994">"Funcționarea ar putea fi necorespunzătoare. Introduceți un dispozitiv de stocare nou."</string> + <string name="ext_media_unmounting_notification_title" msgid="5046532339291216076">"Se deconectează <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmounting_notification_message" msgid="1003926904442321115">"Nu scoateți"</string> <string name="ext_media_init_action" msgid="7952885510091978278">"Configurați"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Scoateți"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index d7108769061b..db9cd0a2c117 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -122,12 +122,13 @@ <string name="roamingText11" msgid="4154476854426920970">"ரோமிங் பேனர் இயக்கத்தில் உள்ளது"</string> <string name="roamingText12" msgid="1189071119992726320">"ரோமிங் பேனர் முடக்கப்பட்டது"</string> <string name="roamingTextSearching" msgid="8360141885972279963">"சேவையைத் தேடுகிறது"</string> - <!-- no translation found for wfcRegErrorTitle (3855061241207182194) --> - <skip /> + <string name="wfcRegErrorTitle" msgid="3855061241207182194">"வைஃபை அழைப்பை அமைக்க முடியவில்லை"</string> <string-array name="wfcOperatorErrorAlertMessages"> <item msgid="3910386316304772394">"வைஃபை மூலம் அழைக்கவும் செய்திகளை அனுப்பவும், முதலில் தொலைத்தொடர்பு நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும். (பிழைக் குறியீடு <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> - <!-- no translation found for wfcOperatorErrorNotificationMessages:0 (7372514042696663278) --> + <string-array name="wfcOperatorErrorNotificationMessages"> + <item msgid="7372514042696663278">"உங்கள் மொபைல் நிறுவனத்துடன் வைஃபை அழைப்பைப் பதிவுசெய்வதில் சிக்கல்: <xliff:g id="CODE">%1$s</xliff:g>"</item> + </string-array> <string-array name="wfcSpnFormats"> <item msgid="6830082633573257149">"%s"</item> <item msgid="4397097370387921767">"%s வைஃபை அழைப்பு"</item> @@ -1157,8 +1158,7 @@ </plurals> <string name="wifi_available_title" msgid="3817100557900599505">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கவும்"</string> <string name="wifi_available_carrier_network_title" msgid="4527932626916527897">"தொலைத்தொடர்பு சேவை வழங்கும் நிறுவனத்தின் வைஃபை நெட்வொர்க்குடன் இணைக்கிறது"</string> - <!-- no translation found for wifi_available_title_connecting (1139126673968899002) --> - <skip /> + <string name="wifi_available_title_connecting" msgid="1139126673968899002">"வைஃபை நெட்வொர்க்குடன் இணைக்கிறது"</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> @@ -1286,8 +1286,8 @@ <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"படங்களையும் மீடியாவையும் மாற்றலாம்"</string> <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Tap to fix"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> சிதைந்துள்ளது. சரிசெய்ய, தேர்ந்தெடுக்கவும்."</string> <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> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 5f35184240d8..5a22dc515946 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -82,8 +82,7 @@ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"کوئی صوتی سروس نہیں"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"کوئی صوتی سروس یا ہنگامی کالنگ دستیاب نہیں ہے"</string> <string name="RestrictedStateContent" msgid="6538703255570997248">"آپ کے کیریئر نے عارضی طور پر آف کر دیا ہے"</string> - <!-- no translation found for RestrictedStateContentMsimTemplate (673416791370248176) --> - <skip /> + <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> کے لئے آپ کے کیریئر نے عارضی طور پر آف کر دیا ہے"</string> <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"موبائل نیٹ ورک تک رسائی نہیں ہو سکتی"</string> <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"ترجیحی نیٹ ورک تبدیل کر کے دیکھیں۔ تبدیل کرنے کے لیے تھپتھپائیں۔"</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"ہنگامی کالنگ دستیاب نہیں ہے"</string> @@ -498,8 +497,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_not_recognized" msgid="2690661881608146617">"تسلیم شدہ نہیں ہے"</string> - <!-- no translation found for fingerprint_authenticated (5309333983002526448) --> - <skip /> + <string name="fingerprint_authenticated" msgid="5309333983002526448">"فنگر پرنٹ کی تصدیق ہو گئی"</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> @@ -1275,49 +1273,34 @@ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> دیگر ایپس پر ڈسپلے ہو رہی ہے"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"اگر آپ نہیں چاہتے ہیں کہ <xliff:g id="NAME">%s</xliff:g> اس خصوصیت کا استعمال کرے تو ترتیبات کھولنے کیلئے تھپتھپائیں اور اسے بند کریں۔"</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"آف کریں"</string> - <!-- no translation found for ext_media_checking_notification_title (4411133692439308924) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (410185170877285434) --> - <skip /> - <!-- no translation found for ext_media_new_notification_title (1621805083736634077) --> - <skip /> - <!-- no translation found for ext_media_new_notification_message (3673685270558405087) --> - <skip /> + <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> کو چیک کیا جا رہا ہے…"</string> + <string name="ext_media_checking_notification_message" msgid="410185170877285434">"موجودہ مواد کا جائزہ لیا جا رہا ہے"</string> + <string name="ext_media_new_notification_title" msgid="1621805083736634077">"نیا <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_new_notification_message" msgid="3673685270558405087">"سیٹ اپ کرنے کیلئے تھپتھپائیں"</string> <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"تصاویر اور میڈیا منتقل کرنے کیلئے"</string> - <!-- no translation found for ext_media_unmountable_notification_title (4179418065210797130) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (4193858924381066522) --> - <skip /> + <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"<xliff:g id="NAME">%s</xliff:g> کے ساتھ مسئلہ"</string> + <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"درست کرنے کیلئے تھپتھپائیں"</string> + <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> خراب ہے۔ اسے ٹھیک کرنے کیلئے منتخب کریں۔"</string> <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> - <!-- no translation found for ext_media_badremoval_notification_message (8556885808951260574) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (6593814191061956856) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (2110883356419799994) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_title (5046532339291216076) --> - <skip /> - <!-- no translation found for ext_media_unmounting_notification_message (1003926904442321115) --> - <skip /> + <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_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> <string name="ext_media_init_action" msgid="7952885510091978278">"سیٹ اپ کریں"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"خارج کریں"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"دریافت کریں"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> غائب ہے"</string> - <!-- no translation found for ext_media_missing_message (4012389235250987930) --> - <skip /> + <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> - <!-- no translation found for ext_media_move_success_title (7863652232242276066) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (8939137931961728009) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (1604422634177382092) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (7388950499623016135) --> - <skip /> + <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_checking" msgid="6193921557423194949">"چیک کیا جا رہا ہے…"</string> @@ -1865,14 +1848,10 @@ <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM میں آواز کیلئے سہولت نہیں ہے"</string> <string name="mmcc_illegal_ms" msgid="807334478177362062">"آواز کیلئے SIM کو اجازت نہیں ہے"</string> <string name="mmcc_illegal_me" msgid="1950705155760872972">"آواز کیلئے فون کو اجازت نہیں ہے"</string> - <!-- no translation found for mmcc_authentication_reject_msim_template (1217031195834766479) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr_msim_template (5636464607596778986) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms_msim_template (5994323296399913454) --> - <skip /> - <!-- no translation found for mmcc_illegal_me_msim_template (5550259730350571826) --> - <skip /> + <string name="mmcc_authentication_reject_msim_template" msgid="1217031195834766479">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> کو اجازت نہیں ہے"</string> + <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="5636464607596778986">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> فراہم کردہ نہیں ہے"</string> + <string name="mmcc_illegal_ms_msim_template" msgid="5994323296399913454">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> کو اجازت نہیں ہے"</string> + <string name="mmcc_illegal_me_msim_template" msgid="5550259730350571826">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> کو اجازت نہیں ہے"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"پاپ اپ ونڈو"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"ایپ کے ورژن کا درجہ کم ہے یا اس شارٹ کٹ کے ساتھ مطابقت پذیر نہیں ہے"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 12e5dfef9e35..8443a67e0f4d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -27,6 +27,7 @@ <!-- Do not translate. Defines the slots for the right-hand side icons. That is to say, the icons in the status bar that are not notifications. --> <string-array name="config_statusBarIcons"> + <item><xliff:g id="id">@string/status_bar_alarm_clock</xliff:g></item> <item><xliff:g id="id">@string/status_bar_rotate</xliff:g></item> <item><xliff:g id="id">@string/status_bar_headset</xliff:g></item> <item><xliff:g id="id">@string/status_bar_data_saver</xliff:g></item> @@ -44,7 +45,6 @@ <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item> <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item> <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item> - <item><xliff:g id="id">@string/status_bar_alarm_clock</xliff:g></item> <item><xliff:g id="id">@string/status_bar_bluetooth</xliff:g></item> <item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item> <item><xliff:g id="id">@string/status_bar_cast</xliff:g></item> diff --git a/libs/hwui/ProfileData.cpp b/libs/hwui/ProfileData.cpp index f9cf54998032..16966619aace 100644 --- a/libs/hwui/ProfileData.cpp +++ b/libs/hwui/ProfileData.cpp @@ -104,7 +104,8 @@ void ProfileData::dump(int fd) const { dprintf(fd, "\nStats since: %" PRIu64 "ns", mStatStartTime); dprintf(fd, "\nTotal frames rendered: %u", mTotalFrameCount); dprintf(fd, "\nJanky frames: %u (%.2f%%)", mJankFrameCount, - (float)mJankFrameCount / (float)mTotalFrameCount * 100.0f); + mTotalFrameCount == 0 ? 0.0f : + (float)mJankFrameCount / (float)mTotalFrameCount * 100.0f); dprintf(fd, "\n50th percentile: %ums", findPercentile(50)); dprintf(fd, "\n90th percentile: %ums", findPercentile(90)); dprintf(fd, "\n95th percentile: %ums", findPercentile(95)); diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 1602b4b39c91..0a6c45beedf9 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -65,6 +65,8 @@ bool Properties::runningInEmulator = false; bool Properties::debuggingEnabled = false; bool Properties::isolatedProcess = false; +int Properties::contextPriority = 0; + static int property_get_int(const char* key, int defaultValue) { char buf[PROPERTY_VALUE_MAX] = { '\0', diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 81a36574a097..764c50259540 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -271,6 +271,8 @@ public: ANDROID_API static bool debuggingEnabled; ANDROID_API static bool isolatedProcess; + ANDROID_API static int contextPriority; + private: static ProfileType sProfileType; static bool sDisableProfileBars; diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 5b87e1013baf..6e239e357cf6 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -82,6 +82,7 @@ static struct { bool pixelFormatFloat = false; bool glColorSpace = false; bool scRGB = false; + bool contextPriority = false; } EglExtensions; EglManager::EglManager(RenderThread& thread) @@ -168,6 +169,7 @@ void EglManager::initExtensions() { #else EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb"); #endif + EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority"); } bool EglManager::hasEglContext() { @@ -247,10 +249,18 @@ void EglManager::loadConfigs() { } void EglManager::createContext() { - EGLint attribs[] = {EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, EGL_NONE}; + std::vector<EGLint> contextAttributes; + contextAttributes.reserve(5); + contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION); + contextAttributes.push_back(GLES_VERSION); + if (Properties::contextPriority != 0 && EglExtensions.contextPriority) { + contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); + contextAttributes.push_back(Properties::contextPriority); + } + contextAttributes.push_back(EGL_NONE); mEglContext = eglCreateContext( mEglDisplay, EglExtensions.noConfigContext ? ((EGLConfig) nullptr) : mEglConfig, - EGL_NO_CONTEXT, attribs); + EGL_NO_CONTEXT, contextAttributes.data()); LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT, "Failed to create context, error = %s", eglErrorString()); } diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index f98480b28001..d0a2c98f6b6b 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -437,6 +438,7 @@ public final class AudioFormat implements Parcelable { * @param mask a combination of the CHANNEL_IN_* definitions, even CHANNEL_IN_DEFAULT * @return number of channels for the mask */ + @TestApi public static int channelCountFromInChannelMask(int mask) { return Integer.bitCount(mask); } @@ -446,6 +448,7 @@ public final class AudioFormat implements Parcelable { * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT * @return number of channels for the mask */ + @TestApi public static int channelCountFromOutChannelMask(int mask) { return Integer.bitCount(mask); } @@ -492,6 +495,7 @@ public final class AudioFormat implements Parcelable { // CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL /** @hide */ + @TestApi public static int getBytesPerSample(int audioFormat) { switch (audioFormat) { @@ -562,6 +566,7 @@ public final class AudioFormat implements Parcelable { } /** @hide */ + @TestApi public static boolean isEncodingLinearPcm(int audioFormat) { switch (audioFormat) { diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index bc0e43b5e9c6..78884367e3f8 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -66,7 +66,7 @@ import libcore.io.Streams; /** * This is a class for reading and writing Exif tags in a JPEG file or a RAW image file. * <p> - * Supported formats are: JPEG, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW and RAF. + * Supported formats are: JPEG, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW, RAF and HEIF. * <p> * Attribute mutation is supported for JPEG image files. */ @@ -2524,46 +2524,46 @@ public class ExifInterface { private void getHeifAttributes(ByteOrderedDataInputStream in) throws IOException { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { - if (mSeekableFileDescriptor != null) { - retriever.setDataSource(mSeekableFileDescriptor); - } else { - retriever.setDataSource(new MediaDataSource() { - long mPosition; - - @Override - public void close() throws IOException {} + retriever.setDataSource(new MediaDataSource() { + long mPosition; - @Override - public int readAt(long position, byte[] buffer, int offset, int size) - throws IOException { - if (size == 0) { - return 0; - } - if (position < 0) { - return -1; - } - if (mPosition != position) { - in.seek(position); - mPosition = position; - } + @Override + public void close() throws IOException {} - int bytesRead = in.read(buffer, offset, size); - if (bytesRead < 0) { - mPosition = -1; // need to seek on next read - return -1; - } - - mPosition += bytesRead; - return bytesRead; + @Override + public int readAt(long position, byte[] buffer, int offset, int size) + throws IOException { + if (size == 0) { + return 0; + } + if (position < 0) { + return -1; + } + if (mPosition != position) { + in.seek(position); + mPosition = position; } - @Override - public long getSize() throws IOException { + int bytesRead = in.read(buffer, offset, size); + if (bytesRead < 0) { + mPosition = -1; // need to seek on next read return -1; } - }); - } + mPosition += bytesRead; + return bytesRead; + } + + @Override + public long getSize() throws IOException { + return -1; + } + }); + + String exifOffsetStr = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_EXIF_OFFSET); + String exifLengthStr = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_EXIF_LENGTH); String hasImage = retriever.extractMetadata( MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE); String hasVideo = retriever.extractMetadata( @@ -2622,6 +2622,30 @@ public class ExifInterface { ExifAttribute.createUShort(orientation, mExifByteOrder)); } + if (exifOffsetStr != null && exifLengthStr != null) { + int offset = Integer.parseInt(exifOffsetStr); + int length = Integer.parseInt(exifLengthStr); + if (length <= 6) { + throw new IOException("Invalid exif length"); + } + in.seek(offset); + byte[] identifier = new byte[6]; + if (in.read(identifier) != 6) { + throw new IOException("Can't read identifier"); + } + offset += 6; + length -= 6; + if (!Arrays.equals(identifier, IDENTIFIER_EXIF_APP1)) { + throw new IOException("Invalid identifier"); + } + + byte[] bytes = new byte[length]; + if (in.read(bytes) != length) { + throw new IOException("Can't read exif"); + } + readExifSegment(bytes, IFD_TYPE_PRIMARY); + } + if (DEBUG) { Log.d(TAG, "Heif meta: " + width + "x" + height + ", rotation " + rotation); } diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java index 37c578542bf3..9828275e4a9f 100644 --- a/media/java/android/media/Image.java +++ b/media/java/android/media/Image.java @@ -193,6 +193,13 @@ public abstract class Image implements AutoCloseable { public abstract int getTransform(); /** + * Get the scaling mode associated with this frame. + * @return The scaling mode that needs to be applied for this frame. + * @hide + */ + public abstract int getScalingMode(); + + /** * Get the {@link android.hardware.HardwareBuffer HardwareBuffer} handle of the input image * intended for GPU and/or hardware access. * <p> diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java index 72d52d3d06e7..8ec0e353ac73 100644 --- a/media/java/android/media/ImageReader.java +++ b/media/java/android/media/ImageReader.java @@ -871,6 +871,12 @@ public class ImageReader implements AutoCloseable { } @Override + public int getScalingMode() { + throwISEIfImageIsInvalid(); + return mScalingMode; + } + + @Override public HardwareBuffer getHardwareBuffer() { throwISEIfImageIsInvalid(); return nativeGetHardwareBuffer(); @@ -1004,14 +1010,11 @@ public class ImageReader implements AutoCloseable { private long mNativeBuffer; /** - * This field is set by native code during nativeImageSetup(). + * These fields are set by native code during nativeImageSetup(). */ private long mTimestamp; - - /** - * This field is set by native code during nativeImageSetup(). - */ private int mTransform; + private int mScalingMode; private SurfacePlane[] mPlanes; private int mFormat = ImageFormat.UNKNOWN; diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java index 8ee27ae58105..397768af84d1 100644 --- a/media/java/android/media/ImageWriter.java +++ b/media/java/android/media/ImageWriter.java @@ -371,7 +371,7 @@ public class ImageWriter implements AutoCloseable { Rect crop = image.getCropRect(); nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), crop.left, crop.top, - crop.right, crop.bottom, image.getTransform()); + crop.right, crop.bottom, image.getTransform(), image.getScalingMode()); /** * Only remove and cleanup the Images that are owned by this @@ -558,7 +558,7 @@ public class ImageWriter implements AutoCloseable { Rect crop = image.getCropRect(); nativeAttachAndQueueImage(mNativeContext, image.getNativeContext(), image.getFormat(), image.getTimestamp(), crop.left, crop.top, crop.right, crop.bottom, - image.getTransform()); + image.getTransform(), image.getScalingMode()); } /** @@ -676,6 +676,7 @@ public class ImageWriter implements AutoCloseable { private long mTimestamp = DEFAULT_TIMESTAMP; private int mTransform = 0; //Default no transform + private int mScalingMode = 0; //Default frozen scaling mode public WriterSurfaceImage(ImageWriter writer) { mOwner = writer; @@ -721,6 +722,13 @@ public class ImageWriter implements AutoCloseable { } @Override + public int getScalingMode() { + throwISEIfImageIsInvalid(); + + return mScalingMode; + } + + @Override public long getTimestamp() { throwISEIfImageIsInvalid(); @@ -866,11 +874,12 @@ public class ImageWriter implements AutoCloseable { private synchronized native void nativeDequeueInputImage(long nativeCtx, Image wi); private synchronized native void nativeQueueInputImage(long nativeCtx, Image image, - long timestampNs, int left, int top, int right, int bottom, int transform); + long timestampNs, int left, int top, int right, int bottom, int transform, + int scalingMode); private synchronized native int nativeAttachAndQueueImage(long nativeCtx, long imageNativeBuffer, int imageFormat, long timestampNs, int left, - int top, int right, int bottom, int transform); + int top, int right, int bottom, int transform, int scalingMode); private synchronized native void cancelImage(long nativeCtx, Image image); diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index e3fba0cdfa08..1f00c7828098 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -3574,6 +3574,7 @@ final public class MediaCodec { private final static int TYPE_YUV = 1; private final int mTransform = 0; //Default no transform + private final int mScalingMode = 0; //Default frozen scaling mode @Override public int getFormat() { @@ -3600,6 +3601,12 @@ final public class MediaCodec { } @Override + public int getScalingMode() { + throwISEIfImageIsInvalid(); + return mScalingMode; + } + + @Override public long getTimestamp() { throwISEIfImageIsInvalid(); return mTimestamp; diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index 0955dd633c1c..8ab5ec447cf9 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -890,5 +890,14 @@ public class MediaMetadataRetriever */ public static final int METADATA_KEY_VIDEO_FRAME_COUNT = 32; + /** + * @hide + */ + public static final int METADATA_KEY_EXIF_OFFSET = 33; + + /** + * @hide + */ + public static final int METADATA_KEY_EXIF_LENGTH = 34; // Add more here... } diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java index 306870650343..b654214ccb25 100644 --- a/media/java/android/media/VolumeShaper.java +++ b/media/java/android/media/VolumeShaper.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -843,6 +844,7 @@ public final class VolumeShaper implements AutoCloseable { * @return the same {@code Builder} instance. * @throws IllegalArgumentException if flag is not recognized. */ + @TestApi public @NonNull Builder setOptionFlags(@OptionFlag int optionFlags) { if ((optionFlags & ~OPTION_FLAG_PUBLIC_ALL) != 0) { throw new IllegalArgumentException("invalid bits in flag: " + optionFlags); diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java index 1cb4d6728917..24c595f5594e 100644 --- a/media/java/android/media/audiofx/AudioEffect.java +++ b/media/java/android/media/audiofx/AudioEffect.java @@ -494,6 +494,7 @@ public class AudioEffect { * @return true if the device implements the specified effect type, false otherwise. * @hide */ + @TestApi public static boolean isEffectTypeAvailable(UUID type) { AudioEffect.Descriptor[] desc = AudioEffect.queryEffects(); if (desc == null) { @@ -546,6 +547,7 @@ public class AudioEffect { * @throws IllegalStateException * @hide */ + @TestApi public int setParameter(byte[] param, byte[] value) throws IllegalStateException { checkState("setParameter()"); @@ -558,6 +560,7 @@ public class AudioEffect { * @see #setParameter(byte[], byte[]) * @hide */ + @TestApi public int setParameter(int param, int value) throws IllegalStateException { byte[] p = intToByteArray(param); byte[] v = intToByteArray(value); @@ -571,6 +574,7 @@ public class AudioEffect { * @see #setParameter(byte[], byte[]) * @hide */ + @TestApi public int setParameter(int param, short value) throws IllegalStateException { byte[] p = intToByteArray(param); @@ -585,6 +589,7 @@ public class AudioEffect { * @see #setParameter(byte[], byte[]) * @hide */ + @TestApi public int setParameter(int param, byte[] value) throws IllegalStateException { byte[] p = intToByteArray(param); @@ -598,6 +603,7 @@ public class AudioEffect { * @see #setParameter(byte[], byte[]) * @hide */ + @TestApi public int setParameter(int[] param, int[] value) throws IllegalStateException { if (param.length > 2 || value.length > 2) { @@ -649,6 +655,7 @@ public class AudioEffect { * @see #setParameter(byte[], byte[]) * @hide */ + @TestApi public int setParameter(int[] param, byte[] value) throws IllegalStateException { if (param.length > 2) { @@ -677,6 +684,7 @@ public class AudioEffect { * @throws IllegalStateException * @hide */ + @TestApi public int getParameter(byte[] param, byte[] value) throws IllegalStateException { checkState("getParameter()"); @@ -690,6 +698,7 @@ public class AudioEffect { * @see #getParameter(byte[], byte[]) * @hide */ + @TestApi public int getParameter(int param, byte[] value) throws IllegalStateException { byte[] p = intToByteArray(param); @@ -705,6 +714,7 @@ public class AudioEffect { * In case of success, returns the number of meaningful integers in value array. * @hide */ + @TestApi public int getParameter(int param, int[] value) throws IllegalStateException { if (value.length > 2) { @@ -736,6 +746,7 @@ public class AudioEffect { * In case of success, returns the number of meaningful short integers in value array. * @hide */ + @TestApi public int getParameter(int param, short[] value) throws IllegalStateException { if (value.length > 2) { @@ -801,6 +812,7 @@ public class AudioEffect { * In case of success, returns the number of meaningful short integers in value array. * @hide */ + @TestApi public int getParameter(int[] param, short[] value) throws IllegalStateException { if (param.length > 2 || value.length > 2) { @@ -940,6 +952,7 @@ public class AudioEffect { * @param listener * @hide */ + @TestApi public void setParameterListener(OnParameterChangeListener listener) { synchronized (mListenerLock) { mParameterChangeListener = listener; @@ -1001,6 +1014,7 @@ public class AudioEffect { * when a parameter is changed in the effect engine by the controlling application. * @hide */ + @TestApi public interface OnParameterChangeListener { /** * Called on the listener to notify it that a parameter value has changed. @@ -1293,6 +1307,7 @@ public class AudioEffect { /** * @hide */ + @TestApi public static boolean isError(int status) { return (status < 0); } @@ -1300,6 +1315,7 @@ public class AudioEffect { /** * @hide */ + @TestApi public static int byteArrayToInt(byte[] valueBuf) { return byteArrayToInt(valueBuf, 0); @@ -1318,6 +1334,7 @@ public class AudioEffect { /** * @hide */ + @TestApi public static byte[] intToByteArray(int value) { ByteBuffer converter = ByteBuffer.allocate(4); converter.order(ByteOrder.nativeOrder()); @@ -1328,6 +1345,7 @@ public class AudioEffect { /** * @hide */ + @TestApi public static short byteArrayToShort(byte[] valueBuf) { return byteArrayToShort(valueBuf, 0); } @@ -1345,6 +1363,7 @@ public class AudioEffect { /** * @hide */ + @TestApi public static byte[] shortToByteArray(short value) { ByteBuffer converter = ByteBuffer.allocate(2); converter.order(ByteOrder.nativeOrder()); diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index bfb3ea2a353c..c36858ad3d8e 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -46,6 +46,7 @@ #define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID "mNativeBuffer" #define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID "mTimestamp" #define ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID "mTransform" +#define ANDROID_MEDIA_SURFACEIMAGE_SM_JNI_ID "mScalingMode" #define CONSUMER_BUFFER_USAGE_UNKNOWN 0; // ---------------------------------------------------------------------------- @@ -68,6 +69,7 @@ static struct { jfieldID mNativeBuffer; jfieldID mTimestamp; jfieldID mTransform; + jfieldID mScalingMode; jfieldID mPlanes; } gSurfaceImageClassInfo; @@ -315,6 +317,12 @@ static void ImageReader_classInit(JNIEnv* env, jclass clazz) "can't find android/graphics/ImageReader.%s", ANDROID_MEDIA_SURFACEIMAGE_TF_JNI_ID); + gSurfaceImageClassInfo.mScalingMode = env->GetFieldID( + imageClazz, ANDROID_MEDIA_SURFACEIMAGE_SM_JNI_ID, "I"); + LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mScalingMode == NULL, + "can't find android/graphics/ImageReader.%s", + ANDROID_MEDIA_SURFACEIMAGE_SM_JNI_ID); + gSurfaceImageClassInfo.mPlanes = env->GetFieldID( imageClazz, "mPlanes", "[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;"); LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mPlanes == NULL, @@ -606,6 +614,8 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) { static_cast<jlong>(buffer->mTimestamp)); env->SetIntField(image, gSurfaceImageClassInfo.mTransform, static_cast<jint>(buffer->mTransform)); + env->SetIntField(image, gSurfaceImageClassInfo.mScalingMode, + static_cast<jint>(buffer->mScalingMode)); return ACQUIRE_SUCCESS; } diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp index 2b8f9f8933d3..11659e4826c5 100644 --- a/media/jni/android_media_ImageWriter.cpp +++ b/media/jni/android_media_ImageWriter.cpp @@ -421,7 +421,8 @@ static void ImageWriter_cancelImage(JNIEnv* env, jobject thiz, jlong nativeCtx, } static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image, - jlong timestampNs, jint left, jint top, jint right, jint bottom, jint transform) { + jlong timestampNs, jint left, jint top, jint right, jint bottom, jint transform, + jint scalingMode) { ALOGV("%s", __FUNCTION__); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); if (ctx == NULL || thiz == NULL) { @@ -471,6 +472,12 @@ static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, j return; } + res = native_window_set_scaling_mode(anw.get(), scalingMode); + if (res != OK) { + jniThrowRuntimeException(env, "Set scaling mode failed"); + return; + } + // Finally, queue input buffer res = anw->queueBuffer(anw.get(), buffer, fenceFd); if (res != OK) { @@ -493,7 +500,7 @@ static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, j static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jlong nativeBuffer, jint imageFormat, jlong timestampNs, jint left, jint top, - jint right, jint bottom, jint transform) { + jint right, jint bottom, jint transform, jint scalingMode) { ALOGV("%s", __FUNCTION__); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); if (ctx == NULL || thiz == NULL) { @@ -536,8 +543,8 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat } sp < ANativeWindow > anw = surface; - // Step 2. Set timestamp, crop and transform. Note that we do not need unlock the image because - // it was not locked. + // Step 2. Set timestamp, crop, transform and scaling mode. Note that we do not need unlock the + // image because it was not locked. ALOGV("timestamp to be queued: %" PRId64, timestampNs); res = native_window_set_buffers_timestamp(anw.get(), timestampNs); if (res != OK) { @@ -562,6 +569,12 @@ static jint ImageWriter_attachAndQueueImage(JNIEnv* env, jobject thiz, jlong nat return res; } + res = native_window_set_scaling_mode(anw.get(), scalingMode); + if (res != OK) { + jniThrowRuntimeException(env, "Set scaling mode failed"); + return res; + } + // Step 3. Queue Image. res = anw->queueBuffer(anw.get(), buffer->mGraphicBuffer.get(), /*fenceFd*/ -1); @@ -797,9 +810,9 @@ static JNINativeMethod gImageWriterMethods[] = { {"nativeInit", "(Ljava/lang/Object;Landroid/view/Surface;II)J", (void*)ImageWriter_init }, {"nativeClose", "(J)V", (void*)ImageWriter_close }, - {"nativeAttachAndQueueImage", "(JJIJIIIII)I", (void*)ImageWriter_attachAndQueueImage }, + {"nativeAttachAndQueueImage", "(JJIJIIIIII)I", (void*)ImageWriter_attachAndQueueImage }, {"nativeDequeueInputImage", "(JLandroid/media/Image;)V", (void*)ImageWriter_dequeueImage }, - {"nativeQueueInputImage", "(JLandroid/media/Image;JIIIII)V", (void*)ImageWriter_queueImage }, + {"nativeQueueInputImage", "(JLandroid/media/Image;JIIIIII)V", (void*)ImageWriter_queueImage }, {"cancelImage", "(JLandroid/media/Image;)V", (void*)ImageWriter_cancelImage }, }; diff --git a/packages/CarrierDefaultApp/res/values-eu/strings.xml b/packages/CarrierDefaultApp/res/values-eu/strings.xml index f98a192f3948..81bd6f85e50d 100644 --- a/packages/CarrierDefaultApp/res/values-eu/strings.xml +++ b/packages/CarrierDefaultApp/res/values-eu/strings.xml @@ -5,7 +5,7 @@ <string name="android_system_label" msgid="2797790869522345065">"Telefonia mugikorreko operadorea"</string> <string name="portal_notification_id" msgid="5155057562457079297">"Agortu egin dira datu mugikorrak"</string> <string name="no_data_notification_id" msgid="668400731803969521">"Desaktibatu da datu-konexioa"</string> - <string name="portal_notification_detail" msgid="2295729385924660881">"Sakatu hau %s gunera joateko"</string> + <string name="portal_notification_detail" msgid="2295729385924660881">"Sakatu hau %s webgunera joateko"</string> <string name="no_data_notification_detail" msgid="3112125343857014825">"Jarri harremanetan %s operadorearekin"</string> <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Ez dago datu-konexiorik"</string> <string name="no_mobile_data_connection" msgid="544980465184147010">"Gehitu datuak eta ibiltaritza-plana %s bidez"</string> diff --git a/packages/InputDevices/res/raw/keyboard_layout_polish.kcm b/packages/InputDevices/res/raw/keyboard_layout_polish.kcm new file mode 100644 index 000000000000..559ec07705b2 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_polish.kcm @@ -0,0 +1,327 @@ +# 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. + +# +# Polish (qwerty) keyboard layout. +# + +type OVERLAY + +### ROW 1 + +key GRAVE { + label: '`' + base: '`' + shift: '~' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' +} + +key 4 { + label: '4' + base: '4' + shift: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '^' +} + +key 7 { + label: '7' + base: '7' + shift: '&' +} + +key 8 { + label: '8' + base: '8' + shift: '*' +} + +key 9 { + label: '9' + base: '9' + shift: '(' +} + +key 0 { + label: '0' + base: '0' + shift: ')' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} + +key EQUALS { + label: '=' + base: '=' + shift: '+' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u0119' + ralt+shift, ralt+capslock: '\u0118' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' + ralt: '\u00F3' + ralt+shift, ralt+capslock: '\u00D3' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '[' + base: '[' + shift: '{' +} + +key RIGHT_BRACKET { + label: ']' + base: ']' + shift: '}' +} + +key BACKSLASH { + label: '\\' + base: '\\' + shift: '|' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u0105' + ralt+shift, ralt+capslock: '\u0104' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u015b' + ralt+shift, ralt+capslock: '\u015a' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' + ralt: '\u0142' + ralt+shift, ralt+capslock: '\u0141' +} + +key SEMICOLON { + label: ';' + base: ';' + shift: ':' +} + +key APOSTROPHE { + label: '\'' + base: '\'' + shift: '"' +} + +### ROW 4 + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' + ralt: '\u017c' + ralt+shift, ralt+capslock: '\u017b' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' + ralt: '\u017a' + ralt+shift, ralt+capslock: '\u0179' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' + ralt: '\u0107' + ralt+shift, ralt+capslock: '\u0106' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' + ralt: '\u0144' + ralt+shift, ralt+capslock: '\u0143' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: '<' +} + +key PERIOD { + label: '.' + base: '.' + shift: '>' +} + +key SLASH { + label: '/' + base: '/' + shift: '?' +} diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml index 61d3234a1f44..5fdc4a6a4505 100644 --- a/packages/InputDevices/res/values/strings.xml +++ b/packages/InputDevices/res/values/strings.xml @@ -125,4 +125,7 @@ <!-- Azerbaijani keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_azerbaijani">Azerbaijani</string> + + <!-- Polish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_polish">Polish</string> </resources> diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml index c6bfc1f65be2..1807aeae0da3 100644 --- a/packages/InputDevices/res/xml/keyboard_layouts.xml +++ b/packages/InputDevices/res/xml/keyboard_layouts.xml @@ -159,4 +159,8 @@ <keyboard-layout android:name="keyboard_layout_azerbaijani" android:label="@string/keyboard_layout_azerbaijani" android:keyboardLayout="@raw/keyboard_layout_azerbaijani" /> + + <keyboard-layout android:name="keyboard_layout_polish" + android:label="@string/keyboard_layout_polish" + android:keyboardLayout="@raw/keyboard_layout_polish" /> </keyboard-layouts> diff --git a/packages/PrintSpooler/res/values-bs/strings.xml b/packages/PrintSpooler/res/values-bs/strings.xml index 2e9bfa317c64..e7f6d13b3c2b 100644 --- a/packages/PrintSpooler/res/values-bs/strings.xml +++ b/packages/PrintSpooler/res/values-bs/strings.xml @@ -42,7 +42,7 @@ <string name="page_description_template" msgid="6831239682256197161">"Strana <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> od <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string> <string name="summary_template" msgid="8899734908625669193">"Rezime, primjeraka <xliff:g id="COPIES">%1$s</xliff:g>, veličina papira <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string> <string name="expand_handle" msgid="7282974448109280522">"Regulator za proširivanje"</string> - <string name="collapse_handle" msgid="6886637989442507451">"Regulator za skupljanje"</string> + <string name="collapse_handle" msgid="6886637989442507451">"Regulator za sužavanje"</string> <string name="print_button" msgid="645164566271246268">"Štampaj"</string> <string name="savetopdf_button" msgid="2976186791686924743">"Sačuvaj u PDF"</string> <string name="print_options_expanded" msgid="6944679157471691859">"Opcije za štampanje su proširene"</string> diff --git a/packages/PrintSpooler/res/values-ne/strings.xml b/packages/PrintSpooler/res/values-ne/strings.xml index 18f96dde9e07..da49afbc3528 100644 --- a/packages/PrintSpooler/res/values-ne/strings.xml +++ b/packages/PrintSpooler/res/values-ne/strings.xml @@ -70,7 +70,7 @@ <string name="print_no_printers" msgid="4869403323900054866">"कुनै प्रिन्टरहरू भेटाइएन"</string> <string name="cannot_add_printer" msgid="7840348733668023106">"प्रिन्टरहरू थप्न सक्दैन"</string> <string name="select_to_add_printers" msgid="3800709038689830974">"प्रिन्टर थप्नका लागि चयन गर्नुहोस्"</string> - <string name="enable_print_service" msgid="3482815747043533842">"सक्षम गर्नका लागि चयन गर्नुहोस्"</string> + <string name="enable_print_service" msgid="3482815747043533842">"सक्षम गर्नाका लागि चयन गर्नुहोस्"</string> <string name="enabled_services_title" msgid="7036986099096582296">"सक्षम गरिएका सेवाहरू"</string> <string name="recommended_services_title" msgid="3799434882937956924">"सिफारिस गरिएका सेवाहरू"</string> <string name="disabled_services_title" msgid="7313253167968363211">"असक्षम गरिएका सेवाहरू"</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 0c617bace1db..a181ee23873d 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -40,10 +40,8 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ৰ মাধ্যমেদি সংযোগ কৰা হৈছে"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"সংযোজিত, ইণ্টাৰনেট নাই"</string> - <!-- no translation found for wifi_status_no_internet (5784710974669608361) --> - <skip /> - <!-- no translation found for wifi_status_sign_in_required (123517180404752756) --> - <skip /> + <string name="wifi_status_no_internet" msgid="5784710974669608361">"ইণ্টাৰনেট সংযোগ নাই"</string> + <string name="wifi_status_sign_in_required" msgid="123517180404752756">"ছাইন ইন কৰা দৰকাৰী"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"একচেছ পইণ্ট কিছু সময়ৰ বাবে পূৰ্ণ হৈ আছে"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"%1$sৰ যোগেৰে সংযোজিত"</string> <string name="available_via_carrier" msgid="1469036129740799053">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string> @@ -67,12 +65,9 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"সংযোগ কৰা হ\'ল (ফ\'ন নাই), বেটাৰিৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"সংযোগ কৰা হ\'ল (মিডিয়া নাই), বেটাৰিৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"সংযোগ কৰা হ\'ল (কোনো ফ\'ন বা মিডিয়া নাই), বেটাৰিৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <!-- no translation found for bluetooth_active_battery_level (3149689299296462009) --> - <skip /> - <!-- no translation found for bluetooth_battery_level (1447164613319663655) --> - <skip /> - <!-- no translation found for bluetooth_active_no_battery_level (8380223546730241956) --> - <skip /> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"সক্ৰিয়, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি"</string> + <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি"</string> + <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"সক্ৰিয়"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়াৰ অডিঅ’"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফ\'ন কলসমূহ"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ফাইল স্থানান্তৰণ"</string> @@ -119,14 +114,10 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"হেডফ\'ন"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ইনপুট সম্পৰ্কীয় বাহ্য় ডিভাইচ"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ব্লুটুথ"</string> - <!-- no translation found for bluetooth_hearingaid_left_pairing_message (7378813500862148102) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_pairing_message (1550373802309160891) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_left_battery_level (8797811465352097562) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_battery_level (7309476148173459677) --> - <skip /> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"বাওঁফালৰ শ্ৰৱণ যন্ত্ৰটো যোৰ পতোৱা হৈছে…"</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"সোঁফালৰ শ্ৰৱণ যন্ত্ৰটো যোৰ পতোৱা হৈছে…"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি বাকী আছে"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"সোঁ - বেটাৰি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"ৱাই-ফাই অফহৈ আছে।"</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"ৱাইফাই সংযোগ বিচ্ছিন্ন হৈ আছে।"</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ৱাই-ফাই এদাল দণ্ড।"</string> @@ -246,15 +237,12 @@ <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"স্বয়ংক্ৰিয়"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"ব্যক্তিগত ডিএনএছ প্ৰদানকাৰীৰ হোষ্টনাম"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"ডিএনএছ সেৱা যোগানকাৰীৰ হ\'ষ্টনাম দিয়ক"</string> - <!-- no translation found for private_dns_mode_provider_failure (231837290365031223) --> - <skip /> + <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"সংযোগ কৰিব পৰা নগ\'ল"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"বেতাঁৰ ডিছপ্লে প্ৰমাণপত্ৰৰ বাবে বিকল্পসমূহ দেখুৱাওক"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ৱাই-ফাই লগিঙৰ মাত্ৰা বঢ়াওক, Wi‑Fi পিকাৰত প্ৰতি SSID RSSI দেখুৱাওক"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ৱাই-ফাই নেটৱৰ্কৰ লগত সংযোগ কৰি থকাৰ সময়ত MAC ঠিকনা যাদৃচ্ছিক কৰক"</string> - <!-- no translation found for wifi_metered_label (4514924227256839725) --> - <skip /> - <!-- no translation found for wifi_unmetered_label (6124098729457992931) --> - <skip /> + <string name="wifi_metered_label" msgid="4514924227256839725">"নিৰিখ-নিৰ্দিষ্ট"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"নিৰিখ অনিৰ্দিষ্ট"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"লগাৰৰ বাফাৰৰ আকাৰ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"প্ৰতিটো লগ বাফাৰত ল\'গাৰৰ আকাৰ বাছনি কৰক"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"লগাৰৰ স্থায়ী সঞ্চয়াগাৰৰ বস্তুবোৰ মচিবনে?"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index faa7eb0fc229..499a2fb54a32 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -114,8 +114,8 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"Навушнікі"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"Перыферыйная прылада ўводу"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"Bluetooth"</string> - <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Спалучаецца левы навушнік…"</string> - <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Спалучаецца правы навушнік…"</string> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Спалучаецца левы слыхавы апарат…"</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Спалучаецца правы слыхавы апарат…"</string> <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Левы – узровень зараду <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Правы – узровень зараду <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi выключаны."</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 7f3c954d44b6..6b37300f6dec 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -40,10 +40,8 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s মাধ্যমে সংযুক্ত হয়েছে"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"সংযুক্ত, ইন্টারনেট নেই"</string> - <!-- no translation found for wifi_status_no_internet (5784710974669608361) --> - <skip /> - <!-- no translation found for wifi_status_sign_in_required (123517180404752756) --> - <skip /> + <string name="wifi_status_no_internet" msgid="5784710974669608361">"ইন্টারনেট কানেকশন নেই"</string> + <string name="wifi_status_sign_in_required" msgid="123517180404752756">"সাইন-ইন করা দরকার"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"এই মুহূর্তে অ্যাক্সেস পয়েন্টের কোনও কানেকশন ফাঁকা নেই"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s এর মাধ্যমে সংযুক্ত হয়েছে"</string> <string name="available_via_carrier" msgid="1469036129740799053">"%1$s এর মাধ্যমে পাওয়া যাচ্ছে"</string> @@ -67,12 +65,9 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"কানেক্ট করা আছে (ফোনের অডিও ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"কানেক্ট করা আছে (মিডিয়ার অডিও ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"কানেক্ট করা আছে (ফোনের বা মিডিয়ার অডিও ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <!-- no translation found for bluetooth_active_battery_level (3149689299296462009) --> - <skip /> - <!-- no translation found for bluetooth_battery_level (1447164613319663655) --> - <skip /> - <!-- no translation found for bluetooth_active_no_battery_level (8380223546730241956) --> - <skip /> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"চালু আছে, চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_battery_level" msgid="1447164613319663655">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"চালু আছে"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়া অডিও"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফোন কল"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ফাইল স্থানান্তর"</string> @@ -119,14 +114,10 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"হেডফোন"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"পেরিফেরাল ইনপুট"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ব্লুটুথ"</string> - <!-- no translation found for bluetooth_hearingaid_left_pairing_message (7378813500862148102) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_pairing_message (1550373802309160891) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_left_battery_level (8797811465352097562) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_battery_level (7309476148173459677) --> - <skip /> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"বাঁদিকের হিয়ারিং এডটি পেয়ার করা হচ্ছে..."</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"ডানদিকের হিয়ারিং এড পেয়ার করা হচ্ছে…"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> চার্জ বাকি আছে"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"ডানদিকের - চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"ওয়াই ফাই বন্ধ৷"</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"ওয়াই ফাই এর সংযোগ বিচ্ছিন্ন হয়েছে৷"</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ওয়াই ফাই এ একটি দণ্ড৷"</string> @@ -246,15 +237,12 @@ <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"অটোমেটিক"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"ব্যক্তিগত ডিএনএস প্রদানকারীর হোস্টনেম"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"ডিএনএস প্রদানকারীর হোস্টনেম লিখুন"</string> - <!-- no translation found for private_dns_mode_provider_failure (231837290365031223) --> - <skip /> + <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"কানেক্ট করা যায়নি"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ওয়াই-ফাই নেটওয়ার্কে সংযুক্ত করার সময় MAC অ্যাড্রেস র্যান্ডমাইজ করুন"</string> - <!-- no translation found for wifi_metered_label (4514924227256839725) --> - <skip /> - <!-- no translation found for wifi_unmetered_label (6124098729457992931) --> - <skip /> + <string name="wifi_metered_label" msgid="4514924227256839725">"পরিমাপ করা"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"পরিমাপ করা নয়"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"লগার বাফারের আকারগুলি"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"লগ বাফার প্রতি অপেক্ষাকৃত বড় আকারগুলির বেছে নিন"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"লগারের স্টোরেজ সাফ করবেন?"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index a5b92de8d1f7..2909265ec0d4 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -40,10 +40,8 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"Connectada mitjançant %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connectada, sense Internet"</string> - <!-- no translation found for wifi_status_no_internet (5784710974669608361) --> - <skip /> - <!-- no translation found for wifi_status_sign_in_required (123517180404752756) --> - <skip /> + <string name="wifi_status_no_internet" msgid="5784710974669608361">"Sense connexió a Internet"</string> + <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Cal iniciar la sessió"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"El punt d\'accés està temporalment ple"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"Connectat mitjançant %1$s"</string> <string name="available_via_carrier" msgid="1469036129740799053">"Disponible mitjançant %1$s"</string> @@ -67,12 +65,9 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connectat (sense accés al telèfon), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connectat (sense accés al contingut multimèdia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connectat (sense accés al telèfon ni al contingut multimèdia), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> - <!-- no translation found for bluetooth_active_battery_level (3149689299296462009) --> - <skip /> - <!-- no translation found for bluetooth_battery_level (1447164613319663655) --> - <skip /> - <!-- no translation found for bluetooth_active_no_battery_level (8380223546730241956) --> - <skip /> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Actiu, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actiu"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Àudio multimèdia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Trucades telefòniques"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència del fitxer"</string> @@ -119,14 +114,10 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"Auricular"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"Perifèric d\'entrada"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"Bluetooth"</string> - <!-- no translation found for bluetooth_hearingaid_left_pairing_message (7378813500862148102) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_pairing_message (1550373802309160891) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_left_battery_level (8797811465352097562) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_battery_level (7309476148173459677) --> - <skip /> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"S\'està vinculant l\'audiòfon esquerre…"</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"S\'està vinculant l\'audiòfon dret…"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Esquerre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Dret: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desactivada."</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconnectada."</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Senyal Wi-Fi: una barra."</string> @@ -246,15 +237,12 @@ <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automàtic"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"Nom d\'amfitrió del proveïdor de DNS privat"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Introdueix el nom d\'amfitrió del proveïdor de DNS"</string> - <!-- no translation found for private_dns_mode_provider_failure (231837290365031223) --> - <skip /> + <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No s\'ha pogut connectar"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions de certificació de pantalla sense fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi i mostra\'l per SSID RSSI al Selector de Wi‑Fi"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Aleatoritza l\'adreça MAC quan estiguis connectat a una xarxa Wi-Fi"</string> - <!-- no translation found for wifi_metered_label (4514924227256839725) --> - <skip /> - <!-- no translation found for wifi_unmetered_label (6124098729457992931) --> - <skip /> + <string name="wifi_metered_label" msgid="4514924227256839725">"Amb límit de dades"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"Sense límit de dades"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Mides memòria intermèdia Logger"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Mida Logger per memòria intermèdia"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"Vols esborrar l\'emmagatzematge persistent del registrador?"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 8c353f45666e..f3c732380dc6 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -65,9 +65,9 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen telefon) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen telefon eller medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktiv, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktivt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string> - <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string> + <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivt"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonopkald"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverførsel"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 3d3c66e6c71e..c51841594de7 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -241,8 +241,8 @@ <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de registro de Wi-Fi, mostrar por SSID RSSI en el selector Wi-Fi"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Ordenar las direcciones MAC de forma aleatoria al conectarse a redes Wi‑Fi"</string> - <string name="wifi_metered_label" msgid="4514924227256839725">"Medido"</string> - <string name="wifi_unmetered_label" msgid="6124098729457992931">"No medido"</string> + <string name="wifi_metered_label" msgid="4514924227256839725">"Medida"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"No medida"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de registrador"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Elige el tamaño del Logger por búfer"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"¿Borrar almacenamiento continuo del registrador?"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 6acd2ca8abc8..4919aa90482f 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -40,10 +40,8 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s દ્વારા કનેક્ટ થયેલ"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"કનેક્ટ કર્યું, કોઈ ઇન્ટરનેટ નથી"</string> - <!-- no translation found for wifi_status_no_internet (5784710974669608361) --> - <skip /> - <!-- no translation found for wifi_status_sign_in_required (123517180404752756) --> - <skip /> + <string name="wifi_status_no_internet" msgid="5784710974669608361">"ઇન્ટરનેટ ઍક્સેસ નથી"</string> + <string name="wifi_status_sign_in_required" msgid="123517180404752756">"સાઇન ઇન આવશ્યક"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ઍક્સેસ પૉઇન્ટ અસ્થાયીરૂપે ભરાયેલ છે"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s દ્વારા કનેક્ટ થયેલ"</string> <string name="available_via_carrier" msgid="1469036129740799053">"%1$s દ્વારા ઉપલબ્ધ"</string> @@ -67,12 +65,9 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ ફોન નથી), બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ મીડિયા નથી), બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ ફોન અથવા મીડિયા નથી), બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <!-- no translation found for bluetooth_active_battery_level (3149689299296462009) --> - <skip /> - <!-- no translation found for bluetooth_battery_level (1447164613319663655) --> - <skip /> - <!-- no translation found for bluetooth_active_no_battery_level (8380223546730241956) --> - <skip /> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"સક્રિય, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string> + <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string> + <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"સક્રિય"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"મીડિયા ઑડિઓ"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ફોન કૉલ"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ફાઇલ સ્થાનાંતરણ"</string> @@ -119,14 +114,10 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"હેડફોન"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ઇનપુટ પેરિફેરલ"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"બ્લૂટૂથ"</string> - <!-- no translation found for bluetooth_hearingaid_left_pairing_message (7378813500862148102) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_pairing_message (1550373802309160891) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_left_battery_level (8797811465352097562) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_battery_level (7309476148173459677) --> - <skip /> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"ડાબી બાજુના શ્રવણ યંત્ર સાથે જોડાણ કરી રહ્યાં છીએ…"</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"જમણી બાજુના શ્રવણ યંત્ર સાથે જોડાણ કરી રહ્યાં છીએ…"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"ડાબે - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"જમણી બાજુની - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi બંધ."</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi ડિસ્કનેક્ટ થયું."</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi એક બાર."</string> @@ -246,15 +237,12 @@ <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"આપમેળે"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"ખાનગી DNS પ્રદાતા હોસ્ટનું નામ"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"DNS પ્રદાતાના હોસ્ટનું નામ દાખલ કરો"</string> - <!-- no translation found for private_dns_mode_provider_failure (231837290365031223) --> - <skip /> + <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"કનેક્ટ કરી શકાયું નથી"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"વાઇ-ફાઇ લોગિંગ સ્તર વધારો, વાઇ-ફાઇ પીકરમાં SSID RSSI દીઠ બતાવો"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"વાઇ-ફાઇ નેટવર્ક સાથે જ્યારે કનેક્ટ કરી રહ્યાં હોય ત્યારે MAC ઍડ્રેસને રેન્ડમાઇઝ કરો"</string> - <!-- no translation found for wifi_metered_label (4514924227256839725) --> - <skip /> - <!-- no translation found for wifi_unmetered_label (6124098729457992931) --> - <skip /> + <string name="wifi_metered_label" msgid="4514924227256839725">"મીટર કરેલ"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"મીટર ન કરેલ"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"લોગર બફર કદ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"લૉગ દીઠ લૉગર કદ બફર પસંદ કરો"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"લૉગર નિરંતર સ્ટોરેજ સાફ કરીએ?"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 9b5c5727720b..f15cdd020087 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -40,10 +40,8 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"कनेक्ट हो गया है, लेकिन इंटरनेट नहीं है"</string> - <!-- no translation found for wifi_status_no_internet (5784710974669608361) --> - <skip /> - <!-- no translation found for wifi_status_sign_in_required (123517180404752756) --> - <skip /> + <string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट कनेक्शन नहीं है"</string> + <string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करना ज़रूरी है"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"एक्सेस प्वाइंट फ़िलहाल भरा हुआ है"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s के ज़रिए कनेक्ट"</string> <string name="available_via_carrier" msgid="1469036129740799053">"%1$s के ज़रिए उपलब्ध"</string> @@ -67,12 +65,9 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"जुड़ गया (फ़ोन के ऑडियो को छोड़कर), बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"जुड़ गया (मीडिया ऑडियो को छोड़कर), बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"जुड़ गया (फ़ोन या मीडिया ऑडियो को छोड़कर), बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <!-- no translation found for bluetooth_active_battery_level (3149689299296462009) --> - <skip /> - <!-- no translation found for bluetooth_battery_level (1447164613319663655) --> - <skip /> - <!-- no translation found for bluetooth_active_no_battery_level (8380223546730241956) --> - <skip /> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"चालू, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string> + <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string> + <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"चालू"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडियो"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फ़ोन कॉल"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फ़ाइल स्थानांतरण"</string> @@ -119,14 +114,10 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"हेडफ़ोन"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"इनपुट पेरिफ़ेरल"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ब्लूटूथ"</string> - <!-- no translation found for bluetooth_hearingaid_left_pairing_message (7378813500862148102) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_pairing_message (1550373802309160891) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_left_battery_level (8797811465352097562) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_battery_level (7309476148173459677) --> - <skip /> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"सुनने में मददगार बाईं ओर का डिवाइस जोड़ा जा रहा है…"</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"सुनने में मददगार दाईं ओर का डिवाइस जोड़ा जा रहा है…"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"बाईं ओर का डिवाइस - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"दाईं ओर का डिवाइस - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"वाई-फ़ाई बंद है."</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"वाई-फ़ाई डिसकनेक्ट है."</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"वाई-फ़ाई का एक बार है."</string> @@ -246,15 +237,12 @@ <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"अपने आप"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"निजी DNS सेवा देने वाले का होस्टनाम"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"DNS सेवा देने वाले का होस्टनाम डालें"</string> - <!-- no translation found for private_dns_mode_provider_failure (231837290365031223) --> - <skip /> + <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"कनेक्ट नहीं हो सका"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस दिखाई देने के लिए प्रमाणन विकल्प दिखाएं"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाई-फ़ाई प्रवेश स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"वाई-फ़ाई से जुड़ते समय अलग-अलग एमएसी पते इस्तेमाल करें"</string> - <!-- no translation found for wifi_metered_label (4514924227256839725) --> - <skip /> - <!-- no translation found for wifi_unmetered_label (6124098729457992931) --> - <skip /> + <string name="wifi_metered_label" msgid="4514924227256839725">"डेटा इस्तेमाल करने की सीमा तय की गई है"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"डेटा इस्तेमाल करने की सीमा तय नहीं की गई है"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफ़र आकार"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"प्रति लॉग बफ़र लॉगर आकार चुनें"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"लॉगर सतत मेमोरी साफ़ करें?"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index eb611ac35ea5..0150f326f920 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -65,7 +65,7 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"Terhubung (tanpa ponsel), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Terhubung (tanpa media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Terhubung (tanpa ponsel atau media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktif, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterai"</string> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Aktif, baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktif"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string> @@ -116,8 +116,8 @@ <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"Bluetooth"</string> <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Menyambungkan alat bantu dengar sebelah kiri…"</string> <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Menyambungkan alat bantu dengar sebelah kanan…"</string> - <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Kiri - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterai"</string> - <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Kanan - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterai"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Kiri - baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Kanan - baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi tidak aktif."</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi tidak tersambung."</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi satu baris."</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 38251b321b4b..9eca2b2e9293 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -65,7 +65,7 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connesso (telefono escluso), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connesso (contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connesso (telefono o contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Attivo, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria"</string> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Attivo - Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level" msgid="1447164613319663655">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Attivo"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimediale"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index fa29adc05e8f..9547d901664a 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -114,8 +114,8 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"Слушалка"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"Периферен влез"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"Bluetooth"</string> - <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Се спарува лев апарат за слушање…"</string> - <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Се спарува десен апарат за слушање…"</string> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Се спарува лево слушно помагало…"</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Се спарува десно слушно помагало…"</string> <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Лево - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string> <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Десно - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi е исклучено."</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index e3f996a4febb..22ea56c32ecf 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -114,7 +114,7 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"နားကြပ်"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ချိတ်ဆက်အသုံးပြုရသည့် စက်ပစ္စည်းများ"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ဘလူးတုသ်"</string> - <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"ဘယ်ဘက် နားကြီးကိရိယာကို တွဲချိတ်နေသည်…"</string> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"ဘယ်ဘက် နားကြားကိရိယာကို တွဲချိတ်နေသည်…"</string> <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"ညာဘက် နားကြားကိရိယာကို တွဲချိတ်နေသည်…"</string> <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"ဘယ်ဘက် − ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"ညာဘက် − ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> @@ -241,8 +241,8 @@ <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi ကွန်ရက်များသို့ ချိတ်ဆက်သည့်အခါ MAC လိပ်စာ ကျပန်းပြုလုပ်ခြင်း"</string> - <string name="wifi_metered_label" msgid="4514924227256839725">"မိမိအသုံးပြုမှုအလိုက် ကောက်ခံထားသည်"</string> - <string name="wifi_unmetered_label" msgid="6124098729457992931">"မိမိအသုံးပြုမှုအလိုက် ကောက်ခံခြင်းမရှိပါ"</string> + <string name="wifi_metered_label" msgid="4514924227256839725">"အခမဲ့ မဟုတ်ပါ"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"အခမဲ့"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"လော့ဂါး ဘာဖား ဆိုက်များ"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"လော့ ဘာဖားတွက် လော့ဂါးဆိုက် ရွေး"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"မှတ်တမ်းထိန်းသိမ်းပေးသည့် သိုလှောင်ခန်းကို ရှင်းလင်းမလား။"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index f6352c064801..434823fa960b 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -116,8 +116,8 @@ <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"Bluetooth"</string> <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Se asociază aparatul auditiv stâng…"</string> <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Se asociază aparatul auditiv drept…"</string> - <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Stâng - baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Drept - baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Stânga – baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Dreapta – baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi dezactivat."</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi deconectat."</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Semnal Wi-Fi: o bară."</string> @@ -241,8 +241,8 @@ <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Afișează aleatoriu adresa MAC când te conectezi la rețele Wi‑Fi"</string> - <string name="wifi_metered_label" msgid="4514924227256839725">"Contorizat"</string> - <string name="wifi_unmetered_label" msgid="6124098729457992931">"Necontorizat"</string> + <string name="wifi_metered_label" msgid="4514924227256839725">"Contorizată"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"Necontorizată"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Dimensiunile tamponului jurnalului"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Dimensiuni jurnal / tampon jurnal"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"Ștergeți stocarea permanentă a jurnalului?"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index fd2f1ea00385..8162a7608dc9 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -40,10 +40,8 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"منسلک بذریعہ %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"دستیاب بذریعہ %1$s"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"منسلک، انٹرنیٹ نہیں ہے"</string> - <!-- no translation found for wifi_status_no_internet (5784710974669608361) --> - <skip /> - <!-- no translation found for wifi_status_sign_in_required (123517180404752756) --> - <skip /> + <string name="wifi_status_no_internet" msgid="5784710974669608361">"انٹرنیٹ نہیں ہے"</string> + <string name="wifi_status_sign_in_required" msgid="123517180404752756">"سائن ان درکار ہے"</string> <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"رسائی پوائنٹ عارضی طور پر فُل ہے"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"منسلک بذریعہ %1$s"</string> <string name="available_via_carrier" msgid="1469036129740799053">"دستیاب بذریعہ %1$s"</string> @@ -67,12 +65,9 @@ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"منسلک ہے (فون کے علاوہ)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"منسلک ہے (میڈیا کے علاوہ)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"منسلک ہے (فون یا میڈیا کے علاوہ)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <!-- no translation found for bluetooth_active_battery_level (3149689299296462009) --> - <skip /> - <!-- no translation found for bluetooth_battery_level (1447164613319663655) --> - <skip /> - <!-- no translation found for bluetooth_active_no_battery_level (8380223546730241956) --> - <skip /> + <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"فعال، <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string> + <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string> + <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"فعال"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"میڈيا آڈیو"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"فون کالز"</string> <string name="bluetooth_profile_opp" msgid="9168139293654233697">"فائل کی منتقلی"</string> @@ -119,14 +114,10 @@ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"ہیڈ فون"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ان پٹ پیریفرل"</string> <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"بلوٹوتھ"</string> - <!-- no translation found for bluetooth_hearingaid_left_pairing_message (7378813500862148102) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_pairing_message (1550373802309160891) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_left_battery_level (8797811465352097562) --> - <skip /> - <!-- no translation found for bluetooth_hearingaid_right_battery_level (7309476148173459677) --> - <skip /> + <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"بائيں جانب کے سماعتی آلہ کا جوڑا بنایا جا رہا ہے…"</string> + <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"دائیں جانب کے سماعتی آلہ کا جوڑا بنایا جا رہا ہے…"</string> + <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"بائيں - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string> + <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"دائيں - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string> <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi آف ہے۔"</string> <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi غیر منسلک ہو گیا۔"</string> <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi ایک بار۔"</string> @@ -246,15 +237,12 @@ <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"خودکار"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"نجی DNS فراہم کنندہ میزبان کا نام"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"DNS فراہم کنندہ کے میزبان کا نام درج کریں"</string> - <!-- no translation found for private_dns_mode_provider_failure (231837290365031223) --> - <skip /> + <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"منسلک نہیں ہو سکا"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi-Fi نیٹ ورکس سے منسلک کرتے وقت MAC پتے کو غیر مرتب کریں"</string> - <!-- no translation found for wifi_metered_label (4514924227256839725) --> - <skip /> - <!-- no translation found for wifi_unmetered_label (6124098729457992931) --> - <skip /> + <string name="wifi_metered_label" msgid="4514924227256839725">"میٹرڈ"</string> + <string name="wifi_unmetered_label" msgid="6124098729457992931">"غیر میٹر شدہ"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"لاگر بفر کے سائز"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"فی لاگ بفر لاگر کے سائز منتخب کریں"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"لاگر مستقل اسٹوریج صاف کریں؟"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 6c068ff1ab4c..dc2eceace066 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -631,7 +631,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile(); if (hearingAidProfile != null) { - mIsActiveDeviceHearingAid = hearingAidProfile.isActiveDevice(mDevice); + mIsActiveDeviceHearingAid = hearingAidProfile.getActiveDevices().contains(mDevice); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index 920500f97223..6c5ecbf2db40 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -136,13 +136,12 @@ public class HearingAidProfile implements LocalBluetoothProfile { public boolean setActiveDevice(BluetoothDevice device) { if (mService == null) return false; - mService.setActiveDevice(device); - return true; + return mService.setActiveDevice(device); } - public boolean isActiveDevice(BluetoothDevice device) { - if (mService == null) return false; - return mService.isActiveDevice(device); + public List<BluetoothDevice> getActiveDevices() { + if (mService == null) return new ArrayList<>(); + return mService.getActiveDevices(); } public boolean isPreferred(BluetoothDevice device) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java index 34a099cb7ea0..00ee575492c2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java @@ -195,8 +195,10 @@ public class LocalBluetoothProfileManager { if (DEBUG) Log.d(TAG, "Adding local HEADSET profile"); mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter, mDeviceManager, this); - addProfile(mHeadsetProfile, HeadsetProfile.NAME, - BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); + addHeadsetProfile(mHeadsetProfile, HeadsetProfile.NAME, + BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED, + BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED, + BluetoothHeadset.STATE_AUDIO_DISCONNECTED); } } else if (mHeadsetProfile != null) { Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing."); @@ -208,8 +210,10 @@ public class LocalBluetoothProfileManager { if(DEBUG) Log.d(TAG, "Adding local HfpClient profile"); mHfpClientProfile = new HfpClientProfile(mContext, mLocalAdapter, mDeviceManager, this); - addProfile(mHfpClientProfile, HfpClientProfile.NAME, - BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); + addHeadsetProfile(mHfpClientProfile, HfpClientProfile.NAME, + BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED, + BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED, + BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED); } } else if (mHfpClientProfile != null) { Log.w(TAG, @@ -277,6 +281,15 @@ public class LocalBluetoothProfileManager { // There is no local SDP record for HID and Settings app doesn't control PBAP Server. } + private void addHeadsetProfile(LocalBluetoothProfile profile, String profileName, + String stateChangedAction, String audioStateChangedAction, int audioDisconnectedState) { + BluetoothEventManager.Handler handler = new HeadsetStateChangeHandler( + profile, audioStateChangedAction, audioDisconnectedState); + mEventManager.addProfileHandler(stateChangedAction, handler); + mEventManager.addProfileHandler(audioStateChangedAction, handler); + mProfileNameMap.put(profileName, profile); + } + private final Collection<ServiceListener> mServiceListeners = new ArrayList<ServiceListener>(); @@ -323,18 +336,47 @@ public class LocalBluetoothProfileManager { cachedDevice = mDeviceManager.addDevice(mLocalAdapter, LocalBluetoothProfileManager.this, device); } + onReceiveInternal(intent, cachedDevice); + } + + protected void onReceiveInternal(Intent intent, CachedBluetoothDevice cachedDevice) { int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0); int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0); if (newState == BluetoothProfile.STATE_DISCONNECTED && oldState == BluetoothProfile.STATE_CONNECTING) { Log.i(TAG, "Failed to connect " + mProfile + " device"); } - cachedDevice.onProfileStateChanged(mProfile, newState); cachedDevice.refresh(); } } + /** Connectivity and audio state change handler for headset profiles. */ + private class HeadsetStateChangeHandler extends StateChangedHandler { + private final String mAudioChangeAction; + private final int mAudioDisconnectedState; + + HeadsetStateChangeHandler(LocalBluetoothProfile profile, String audioChangeAction, + int audioDisconnectedState) { + super(profile); + mAudioChangeAction = audioChangeAction; + mAudioDisconnectedState = audioDisconnectedState; + } + + @Override + public void onReceiveInternal(Intent intent, CachedBluetoothDevice cachedDevice) { + if (mAudioChangeAction.equals(intent.getAction())) { + int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0); + if (newState != mAudioDisconnectedState) { + cachedDevice.onProfileStateChanged(mProfile, BluetoothProfile.STATE_CONNECTED); + } + cachedDevice.refresh(); + } else { + super.onReceiveInternal(intent, cachedDevice); + } + } + } + /** State change handler for NAP and PANU profiles. */ private class PanStateChangedHandler extends StateChangedHandler { diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java index 70816782541d..06e2ee103600 100644 --- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java +++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java @@ -16,6 +16,7 @@ package com.android.settingslib.fuelgauge; +import android.content.pm.PackageManager; import android.os.IDeviceIdleController; import android.os.RemoteException; import android.os.ServiceManager; @@ -24,6 +25,8 @@ import android.support.annotation.VisibleForTesting; import android.util.ArraySet; import android.util.Log; +import com.android.internal.util.ArrayUtils; + /** * Handles getting/changing the whitelist for the exceptions to battery saving features. */ @@ -68,6 +71,19 @@ public class PowerWhitelistBackend { return mSysWhitelistedAppsExceptIdle.contains(pkg); } + public boolean isSysWhitelistedExceptIdle(String[] pkgs) { + if (ArrayUtils.isEmpty(pkgs)) { + return false; + } + for (String pkg : pkgs) { + if (isSysWhitelistedExceptIdle(pkg)) { + return true; + } + } + + return false; + } + public void addApp(String pkg) { try { mDeviceIdleService.addPowerSaveWhitelistApp(pkg); diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java index 8b3da3944088..de29030f5a46 100644 --- a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java +++ b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java @@ -144,7 +144,8 @@ public class PowerUtil { FIFTEEN_MINUTES_MILLIS); // convert the time to a properly formatted string. - DateFormat fmt = DateFormat.getTimeInstance(DateFormat.SHORT); + String skeleton = android.text.format.DateFormat.getTimeFormatString(context); + DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton); Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs)); CharSequence timeString = fmt.format(date); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java index 5a123af02ca4..f591781db5d7 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java @@ -92,7 +92,7 @@ public class PowerWhitelistBackendTest { } @Test - public void testIsSystemWhitelistedExceptIdle() throws Exception { + public void testIsSystemWhitelistedExceptIdle_onePackage() throws Exception { doReturn(new String[]{PACKAGE_TWO}).when( mDeviceIdleService).getSystemPowerWhitelistExceptIdle(); mPowerWhitelistBackend.refreshList(); @@ -100,4 +100,17 @@ public class PowerWhitelistBackendTest { assertThat(mPowerWhitelistBackend.isSysWhitelistedExceptIdle(PACKAGE_ONE)).isFalse(); assertThat(mPowerWhitelistBackend.isSysWhitelistedExceptIdle(PACKAGE_TWO)).isTrue(); } + + @Test + public void testIsSystemWhitelistedExceptIdle_packageArray() throws Exception { + doReturn(new String[]{PACKAGE_TWO}).when( + mDeviceIdleService).getSystemPowerWhitelistExceptIdle(); + mPowerWhitelistBackend.refreshList(); + + final String[] idlePackages = {PACKAGE_ONE, PACKAGE_TWO}; + final String[] normalPackages = {PACKAGE_ONE}; + + assertThat(mPowerWhitelistBackend.isSysWhitelistedExceptIdle(normalPackages)).isFalse(); + assertThat(mPowerWhitelistBackend.isSysWhitelistedExceptIdle(idlePackages)).isTrue(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java index 05247ba37382..dfd48cc99894 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java @@ -42,8 +42,8 @@ public class PowerUtilTest { public static final long THIRTY_HOURS_MILLIS = Duration.ofHours(30).toMillis(); public static final String NORMAL_CASE_EXPECTED_PREFIX = "Should last until about"; public static final String ENHANCED_SUFFIX = " based on your usage"; - // matches a time (ex: '1:15 PM', '2 AM') - public static final String TIME_OF_DAY_REGEX = " (\\d)+:?(\\d)* (AM)|(PM)"; + // matches a time (ex: '1:15 PM', '2 AM', '23:00') + public static final String TIME_OF_DAY_REGEX = " (\\d)+:?(\\d)* ((AM)*)|((PM)*)"; // matches a percentage with parenthesis (ex: '(10%)') public static final String PERCENTAGE_REGEX = " \\(\\d?\\d%\\)"; diff --git a/packages/Shell/res/values-ne/strings.xml b/packages/Shell/res/values-ne/strings.xml index eadfeb9155e8..77ef32a1b6b2 100644 --- a/packages/Shell/res/values-ne/strings.xml +++ b/packages/Shell/res/values-ne/strings.xml @@ -25,9 +25,9 @@ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"उक्त बग सम्बन्धी रिपोर्ट चाँडै नै यस फोनमा देखा पर्नेछ"</string> <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"तपाईंको बग रिपोर्ट आदान प्रदान गर्न चयन गर्नुहोस्"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"तपाईंको बग रिपोर्टलाई साझेदारी गर्न ट्याप गर्नुहोस्"</string> - <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"तपाईंको बग रिपोर्ट स्क्रिनसट बिना आदान प्रदान गर्नका लागि चयन गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुने प्रतीक्षा गर्नुहोस्"</string> - <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"तपाईँको बग रिपोर्टलाई स्क्रिनसट बिना साझेदारी गर्नका लागि ट्याप गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुन प्रतीक्षा गर्नुहोस्"</string> - <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"तपाईँको बग रिपोर्टलाई स्क्रिनसट बिना साझेदारी गर्नका लागि ट्याप गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुन प्रतीक्षा गर्नुहोस्"</string> + <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"तपाईंको बग रिपोर्ट स्क्रिनसट बिना आदान प्रदान गर्नाका लागि चयन गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुने प्रतीक्षा गर्नुहोस्"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"तपाईँको बग रिपोर्टलाई स्क्रिनसट बिना साझेदारी गर्नाका लागि ट्याप गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुन प्रतीक्षा गर्नुहोस्"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"तपाईँको बग रिपोर्टलाई स्क्रिनसट बिना साझेदारी गर्नाका लागि ट्याप गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुन प्रतीक्षा गर्नुहोस्"</string> <string name="bugreport_confirm" msgid="5917407234515812495">"बग रिपोर्टहरूमा प्रणालीका विभिन्न लग फाइलहरूको डेटा हुन्छ जसमा तपाईँले संवेदनशील मानेको डेटा समावेश हुन सक्छ (जस्तै अनुप्रयोगको प्रयोग र स्थान सम्बन्धी डेटा)। तपाईँले विश्वास गर्ने व्यक्ति र अनुप्रयोगहरूसँग मात्र बग रिपोर्टहरूलाई साझेदारी गर्नुहोस्।"</string> <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"फेरि नदेखाउनुहोस्"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रिपोर्टहरू"</string> diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml index 79e54aa45d9a..d72021e27e0b 100644 --- a/packages/SystemUI/res/layout/navigation_layout.xml +++ b/packages/SystemUI/res/layout/navigation_layout.xml @@ -27,13 +27,16 @@ <com.android.systemui.statusbar.phone.NearestTouchFrame android:id="@+id/nav_buttons" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:clipChildren="false" + android:clipToPadding="false"> <LinearLayout android:id="@+id/ends_group" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" + android:clipToPadding="false" android:clipChildren="false" /> <LinearLayout @@ -43,6 +46,7 @@ android:layout_gravity="center" android:gravity="center" android:orientation="horizontal" + android:clipToPadding="false" android:clipChildren="false" /> </com.android.systemui.statusbar.phone.NearestTouchFrame> diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml index 5229f9b3a1f5..54baa4a82a0b 100644 --- a/packages/SystemUI/res/layout/quick_settings_header_info.xml +++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml @@ -41,13 +41,14 @@ android:visibility="invisible"> <ImageView - android:id="@+id/ringer_mode_icon" + android:id="@+id/next_alarm_icon" android:layout_width="@dimen/qs_header_alarm_icon_size" android:layout_height="@dimen/qs_header_alarm_icon_size" + android:src="@drawable/stat_sys_alarm" android:tint="?android:attr/textColorPrimary" /> <TextView - android:id="@+id/ringer_mode_text" + android:id="@+id/next_alarm_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start" @@ -63,14 +64,13 @@ android:backgroundTint="?android:attr/textColorPrimary" /> <ImageView - android:id="@+id/next_alarm_icon" + android:id="@+id/ringer_mode_icon" android:layout_width="@dimen/qs_header_alarm_icon_size" android:layout_height="@dimen/qs_header_alarm_icon_size" - android:src="@drawable/stat_sys_alarm" android:tint="?android:attr/textColorPrimary" /> <TextView - android:id="@+id/next_alarm_text" + android:id="@+id/ringer_mode_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start" diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 0a1896fdee13..c830f79c73a8 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"স্ক্ৰীণশ্বট ছেভ কৰি থকা হৈছে…"</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"স্ক্ৰীণশ্বট ছেভ কৰা হ\'ল"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"আপোনাৰ স্ক্ৰীণশ্বট চাবলৈ টিপক"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"স্ক্ৰীণশ্বট ছেভ কৰিব পৰা নগ\'ল"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"স্ক্ৰীণশ্বট আকৌ ল\'বলৈ চেষ্টা কৰক"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"সঞ্চয়াগাৰত সীমিত খালী ঠাই থকাৰ বাবে স্ক্ৰীণশ্বট ছেভ কৰিব পৰা নগ\'ল"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"এপটোৱে বা আপোনাৰ প্ৰতিষ্ঠানে স্ক্ৰীণশ্বট ল\'বলৈ অনুমতি নিদিয়ে"</string> <string name="usb_preference_title" msgid="6551050377388882787">"ইউএছবিৰে ফাইল স্থানান্তৰণৰ বিকল্পসমূহ"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"সূৰ্যাস্তত অন কৰক"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"সূৰ্যোদয়ৰ লৈকে"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>ত অন কৰক"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> পৰ্যন্ত"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC নিষ্ক্ৰিয় হৈ আছে"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC সক্ষম হৈ আছে"</string> @@ -433,8 +430,7 @@ <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> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"জনানীসমূহ পৰিচালনা কৰক"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"অসুবিধা নিদিব ম\'ডে জাননীসমূহ লুকাই ৰাখিছে"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"এতিয়াই আৰম্ভ কৰক"</string> <string name="empty_shade_text" msgid="708135716272867002">"কোনো জাননী নাই"</string> @@ -633,8 +629,7 @@ <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> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"জাননীক স্নুজ কৰাৰ বিকল্পসমূহ"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"স্নুজ কৰক"</string> <string name="snooze_undo" msgid="6074877317002985129">"আনডু কৰক"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ৰ বাবে স্নুজ কৰক"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index ce39f23fffb6..05d3148a6305 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"স্ক্রিনশট সেভ করা হচ্ছে..."</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"স্ক্রিনশট সেভ করা হয়েছে"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"স্ক্রিনশটটি দেখতে ট্যাপ করুন"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"স্ক্রিনশট সেভ করা যায়নি"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"আবার স্ক্রিনশট নেওয়ার চেষ্টা করুন"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"বেশি জায়গা নেই তাই স্ক্রিনশটটি সেভ করা যাবে না৷"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"এই অ্যাপ বা আপনার প্রতিষ্ঠান স্ক্রিনশট নেওয়ার অনুমতি দেয়নি"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ফাইল স্থানান্তরের বিকল্পগুলি"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"সূর্যাস্তে চালু হবে"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"সূর্যোদয় পর্যন্ত"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> এ চালু হবে"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> পর্যন্ত"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC অক্ষম করা আছে"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC সক্ষম করা আছে"</string> @@ -433,8 +430,7 @@ <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> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"বিজ্ঞপ্তি পরিচালনা করুন"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"\'বিরক্ত করবেন না\' মোড চালু আছে, তাই বিজ্ঞপ্তি লুকিয়ে ফেলা হচ্ছে"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"এখন শুরু করুন"</string> <string name="empty_shade_text" msgid="708135716272867002">"কোনো বিজ্ঞপ্তি নেই"</string> @@ -633,8 +629,7 @@ <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> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"বিজ্ঞপ্তি মনে করিয়ে দেওয়ার বিকল্পগুলি"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"স্নুজ করুন"</string> <string name="snooze_undo" msgid="6074877317002985129">"পূর্বাবস্থায় ফিরুন"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> পরে আবার মনে করানো হবে"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 5b062507eeb6..35e006e38b93 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -504,7 +504,7 @@ <string name="volume_zen_end_now" msgid="6930243045593601084">"Isključi sada"</string> <string name="accessibility_volume_settings" msgid="4915364006817819212">"Postavke zvuka"</string> <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširi"</string> - <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skupi"</string> + <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Suzi"</string> <string name="accessibility_output_chooser" msgid="8185317493017988680">"Promijenite izlazni uređaj"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran je prikačen"</string> <string name="screen_pinning_description" msgid="8909878447196419623">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Nazad."</string> @@ -765,9 +765,9 @@ <string name="accessibility_action_divider_top_50" msgid="6385859741925078668">"Gore 50%"</string> <string name="accessibility_action_divider_top_30" msgid="6201455163864841205">"Gore 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="301433196679548001">"Donji ekran kao cijeli ekran"</string> - <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvaput dodirnite za uređivanje."</string> - <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g> Dvaput dodirnite za dodavanje."</string> - <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>. Dvaput dodirnite za odabir."</string> + <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dodirnite dvaput za uređivanje."</string> + <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g> Dodirnite dvaput za dodavanje."</string> + <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>. Dodirnite dvaput za odabir."</string> <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Pomjeri <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Ukloni <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> je dodan na poziciju <xliff:g id="POSITION">%2$d</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 58f0f7b3afd1..586a29230604 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"S\'està desant la captura de pantalla..."</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"S\'ha desat la captura de pantalla"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"Toca per veure la captura de pantalla"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"No s\'ha pogut desar la captura de pantalla"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Prova de tornar a fer una captura de pantalla"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"La captura de pantalla no es pot desar perquè no hi ha prou espai d\'emmagatzematge"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"L\'aplicació o la teva organització no permeten fer captures de pantalla"</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opcions transf. fitxers USB"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"A la posta de sol"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Fins a l\'alba"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"S\'activarà a les <xliff:g id="TIME">%s</xliff:g>"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"L\'NFC està desactivada"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"L\'NFC està activada"</string> @@ -433,8 +430,7 @@ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> començarà a gravar tot el que es mostri a la pantalla."</string> <string name="media_projection_remember_text" msgid="3103510882172746752">"No ho tornis a mostrar"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Esborra-ho tot"</string> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"Gestiona les notificacions"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"El mode No molestis està amagant notificacions"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"Comença ara"</string> <string name="empty_shade_text" msgid="708135716272867002">"Cap notificació"</string> @@ -633,8 +629,7 @@ <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">"controls de notificació"</string> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcions per posposar la notificació"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"Posposa"</string> <string name="snooze_undo" msgid="6074877317002985129">"DESFÉS"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"S\'ha posposat <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index b6b79cb1be41..cb05035fccaf 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -75,7 +75,7 @@ <string name="screenshot_saved_title" msgid="5637073968117370753">"Screenshot gespeichert"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"Tippe, um deinen Screenshot anzusehen"</string> <string name="screenshot_failed_title" msgid="7612509838919089748">"Screenshot konnte nicht gespeichert werden"</string> - <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Erstelle einen weiteren Screenshot"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Versuche noch einmal, den Screenshot zu erstellen"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Speichern des Screenshots aufgrund von zu wenig Speicher nicht möglich"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Die App oder deine Organisation lässt das Erstellen von Screenshots nicht zu"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 73b0bba8fb79..b4de7f65bb3c 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -531,18 +531,15 @@ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrate"</string> <string name="volume_ringer_status_silent" msgid="6896394161022916369">"Mute"</string> - <!-- no translation found for qs_status_phone_vibrate (204362991135761679) --> - <skip /> - <!-- no translation found for qs_status_phone_muted (5437668875879171548) --> - <skip /> + <string name="qs_status_phone_vibrate" msgid="204362991135761679">"Phone on vibrate"</string> + <string name="qs_status_phone_muted" msgid="5437668875879171548">"Phone muted"</string> <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tap to unmute."</string> <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string> <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap to mute."</string> <string name="volume_dialog_title" msgid="7272969888820035876">"%s volume controls"</string> - <!-- no translation found for volume_dialog_ringer_guidance_ring (3360373718388509040) --> - <skip /> + <string name="volume_dialog_ringer_guidance_ring" msgid="3360373718388509040">"Calls and notifications will ring (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string> <string name="output_title" msgid="5355078100792942802">"Media output"</string> <string name="output_calls_title" msgid="8717692905017206161">"Phone call output"</string> <string name="output_none_found" msgid="5544982839808921091">"No devices found"</string> @@ -693,8 +690,7 @@ <string name="battery" msgid="7498329822413202973">"Battery"</string> <string name="clock" msgid="7416090374234785905">"Clock"</string> <string name="headset" msgid="4534219457597457353">"Headset"</string> - <!-- no translation found for accessibility_long_click_tile (6687350750091842525) --> - <skip /> + <string name="accessibility_long_click_tile" msgid="6687350750091842525">"Open settings"</string> <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Headphones connected"</string> <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset connected"</string> <string name="data_saver" msgid="5037565123367048522">"Data Saver"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index f0faae8dabba..b671dfebdeff 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -851,7 +851,7 @@ <string name="auto_saver_title" msgid="1217959994732964228">"Sakatu bateria-aurrezlea noiz aktibatu antolatzeko"</string> <string name="auto_saver_text" msgid="6324376061044218113">"Aktibatu automatikoki bateriaren %% <xliff:g id="PERCENTAGE">%d</xliff:g> gelditzen denean"</string> <string name="no_auto_saver_action" msgid="8086002101711328500">"Ez"</string> - <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Bateria-aurrezle aktibatu da"</string> + <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Bateria-aurrezlea aktibatu da"</string> <string name="auto_saver_enabled_text" msgid="874711029884777579">"Bateria-aurrezlea automatikoki aktibatuko da bateriaren %% <xliff:g id="PERCENTAGE">%d</xliff:g> gelditzen denean."</string> <string name="open_saver_setting_action" msgid="8314624730997322529">"Ezarpenak"</string> <string name="auto_saver_okay_action" msgid="2701221740227683650">"Ados"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index b6349cdeae45..c42206abbf04 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"સ્ક્રીનશોટ સાચવી રહ્યું છે…"</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"સ્ક્રીનશૉટ સાચવ્યો"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"તમારા સ્ક્રીનશૉટને જોવા માટે ટૅપ કરો"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"સ્ક્રીનશૉટ સાચવી શક્યાં નથી"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ફરીથી સ્ક્રીનશૉટ લેવાનો પ્રયાસ કરો"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"મર્યાદિત સ્ટોરેજ સ્પેસને કારણે સ્ક્રીનશૉટ સાચવી શકાતો નથી"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ઍપ્લિકેશન કે તમારી સંસ્થા દ્વારા સ્ક્રીનશૉટ લેવાની મંજૂરી નથી"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ફાઇલ ટ્રાન્સફર વિકલ્પો"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"સૂર્યાસ્ત વખતે"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"સૂર્યોદય સુધી"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> વાગ્યે"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> સુધી"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC અક્ષમ કરેલ છે"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC સક્ષમ કરેલ છે"</string> @@ -433,8 +430,7 @@ <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> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"સૂચનાઓને મેનેજ કરો"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"ખલેલ પાડશો નહીં નોટિફિકેશન છુપાવી રહ્યું છે"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"હવે પ્રારંભ કરો"</string> <string name="empty_shade_text" msgid="708135716272867002">"કોઈ સૂચનાઓ નથી"</string> @@ -633,8 +629,7 @@ <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> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"સૂચના સ્નૂઝ કરવાના વિકલ્પો"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"સ્નૂઝ કરો"</string> <string name="snooze_undo" msgid="6074877317002985129">"પૂર્વવત્ કરો"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> માટે સ્નૂઝ કરો"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index f2b281c28c8b..13c49f743f7d 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"स्क्रीनशॉट सहेजा जा रहा है..."</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"स्क्रीनशॉट सेव किया गया"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"अपना स्क्रीनशॉट देखने के लिए टैप करें"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"स्क्रीनशॉट सेव नहीं किया जा सका"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"स्क्रीनशॉट दोबारा लेने की कोशिश करें"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"मेमोरी कम होने की वजह से स्क्रीनशॉट सेव नहीं किया जा सका"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ऐप्लिकेशन या आपका संगठन स्क्रीनशॉट लेने की अनुमति नहीं देता"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB फ़ाइल स्थानांतरण विकल्प"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"शाम को चालू की जाएगी"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"सुबह तक चालू रहेगी"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> पर चालू की जाएगी"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> तक"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC बंद है"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC चालू है"</string> @@ -433,8 +430,7 @@ <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> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"सूचनाएं प्रबंधित करें"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"परेशान न करें सुविधा चालू होने की वजह से सूचनाएं नहीं दिखाई जा रही हैं"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"अब शुरू करें"</string> <string name="empty_shade_text" msgid="708135716272867002">"कोई सूचना नहीं मिली"</string> @@ -633,8 +629,7 @@ <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> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"सूचना को स्नूज़ (थोड़ी देर के लिए चुप करना) करने के विकल्प"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"स्नूज़ करें"</string> <string name="snooze_undo" msgid="6074877317002985129">"पहले जैसा करें"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> के लिए याद दिलाया गया"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index f3e15ec3aa23..7a19ad00b304 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"Vistar skjámynd…"</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"Skjámynd vistuð"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"Ýttu til skoða skjámyndina"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"Ekki var hægt að vista skjámynd"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Prófaðu að taka skjámynd aftur"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Ekki tókst að vista skjámynd vegna takmarkaðs geymslupláss"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Forritið eða fyrirtækið þitt leyfir ekki skjámyndatöku"</string> <string name="usb_preference_title" msgid="6551050377388882787">"Valkostir USB-skráaflutnings"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Kveikt við sólsetur"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Til sólarupprásar"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Kveikt klukkan <xliff:g id="TIME">%s</xliff:g>"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Til klukkan <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Slökkt á NFC"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Kveikt á NFC"</string> @@ -433,8 +430,7 @@ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> mun fanga allt sem birtist á skjánum."</string> <string name="media_projection_remember_text" msgid="3103510882172746752">"Ekki sýna þetta aftur"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Hreinsa allt"</string> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"Stjórna tilkynningum"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"„Ónáðið ekki“ felur tilkynningar"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"Byrja núna"</string> <string name="empty_shade_text" msgid="708135716272867002">"Engar tilkynningar"</string> @@ -633,8 +629,7 @@ <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">"tilkynningastýringar"</string> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"þöggunarstillingar tilkynninga"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"Fresta"</string> <string name="snooze_undo" msgid="6074877317002985129">"AFTURKALLA"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"Þaggað í <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 7e9d830e100c..02b285fbadc5 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -53,8 +53,8 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth con tethering"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura metodi di immissione"</string> <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tastiera fisica"</string> - <string name="usb_device_permission_prompt" msgid="1825685909587559679">"Vuoi consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> - <string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Vuoi consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string> + <string name="usb_device_permission_prompt" msgid="1825685909587559679">"Consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> + <string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string> <string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vuoi aprire <xliff:g id="APPLICATION">%1$s</xliff:g> per gestire <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vuoi aprire <xliff:g id="APPLICATION">%1$s</xliff:g> per gestire <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string> <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Nessuna app installata funziona con questo accessorio USB. Altre info su <xliff:g id="URL">%1$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 19b4b5b8374c..eff2a09a8dd1 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ କରାଯାଉଛି…"</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ ହୋଇଛି"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"ସ୍କ୍ରୀନଶଟ୍ ଦେଖିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"ସ୍କ୍ରୀନ୍ଶଟ୍ ସେଭ୍ କରିହେବ ନାହିଁ"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ପୁଣିଥରେ ସ୍କ୍ରୀନ୍ଶଟ୍ ନେବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"ସୀମିତ ଷ୍ଟୋରେଜ୍ ସ୍ପେସ୍ ହେତୁ ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ ହୋଇପାରିବ ନାହିଁ"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ଆପ୍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ଫାଇଲ୍ ଟ୍ରାନ୍ସଫର୍ର ବିକଳ୍ପ"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"ସୂର୍ଯ୍ୟାସ୍ତ ବେଳେ ଅନ୍ ହେବ"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"ସୂର୍ଯ୍ୟୋଦୟ ପର୍ଯ୍ୟନ୍ତ"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>ରେ ଅନ୍ ହେବ"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ଅକ୍ଷମ କରାଯାଇଛି"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ସକ୍ଷମ କରାଯାଇଛି"</string> @@ -433,8 +430,7 @@ <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> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"ବିଜ୍ଞପ୍ତି ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ମୋଡ୍ ଅନ୍ ଥିବାଯୋଗୁଁ ବିଜ୍ଞପ୍ତି ଲୁଚାଇ ଦିଆଯାଉଛି"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string> <string name="empty_shade_text" msgid="708135716272867002">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string> @@ -633,8 +629,7 @@ <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> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ବିଜ୍ଞପ୍ତି ସ୍ନୁଜ୍ ବିକଳ୍ପ"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"ସ୍ନୁଜ୍"</string> <string name="snooze_undo" msgid="6074877317002985129">"ପୂର୍ବାବସ୍ଥାକୁ ଫେରାଇ ଆଣନ୍ତୁ"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ପାଇଁ ସ୍ନୁଜ୍ କରାଗଲା"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index cf0dae5df33d..de39f4b2c0d1 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -74,7 +74,7 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"A guardar captura de ecrã..."</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"Captura de ecrã guardada"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"Toque para ver a captura de ecrã."</string> - <string name="screenshot_failed_title" msgid="7612509838919089748">"Não foi possível gravar a captura de ecrã"</string> + <string name="screenshot_failed_title" msgid="7612509838919089748">"Não foi possível guardar a captura de ecrã"</string> <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Experimente voltar a efetuar a captura de ecrã."</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Não é possível guardar a captura de ecrã devido a espaço de armazenamento limitado."</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"A aplicação ou a sua entidade não permitem tirar capturas de ecrã"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 31c44d2ccef8..bf48c268c9ba 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -358,7 +358,7 @@ <string name="quick_settings_nfc_label" msgid="9012153754816969325">"Модуль NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Модуль NFC отключен"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Модуль NFC включен"</string> - <string name="recents_empty_message" msgid="808480104164008572">"Недавних приложений нет"</string> + <string name="recents_empty_message" msgid="808480104164008572">"Здесь пока ничего нет."</string> <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"Вы очистили всё"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Сведения о приложении"</string> <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Заблокировать в приложении"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 8b341c059eb7..cb215c14de53 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -74,10 +74,8 @@ <string name="screenshot_saving_title" msgid="8242282144535555697">"اسکرین شاٹ محفوظ ہو رہا ہے…"</string> <string name="screenshot_saved_title" msgid="5637073968117370753">"اسکرین شاٹ محفوظ ہو گیا"</string> <string name="screenshot_saved_text" msgid="7574667448002050363">"اپنا اسکرین شاٹ دیکھنے کیلئے تھپتھپائیں"</string> - <!-- no translation found for screenshot_failed_title (7612509838919089748) --> - <skip /> - <!-- no translation found for screenshot_failed_to_save_unknown_text (3637758096565605541) --> - <skip /> + <string name="screenshot_failed_title" msgid="7612509838919089748">"اسکرین شاٹ کو محفوظ نہیں کیا جا سکا"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"دوبارہ اسکرین شاٹ لینے کی کوشش کریں"</string> <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"اسٹوریج کی محدود جگہ کی وجہ سے اسکرین شاٹ کو محفوظ نہیں کیا جا سکتا"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ایپ یا آپ کی تنظیم کی جانب سے اسکرین شاٹس لینے کی اجازت نہیں ہے"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB فائل منتقل کرنیکے اختیارات"</string> @@ -348,8 +346,7 @@ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"غروب آفتاب کے وقت آن ہوگی"</string> <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"طلوع آفتاب تک"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"آن ہوگی بوقت <xliff:g id="TIME">%s</xliff:g>"</string> - <!-- no translation found for quick_settings_secondary_label_until (2749196569462600150) --> - <skip /> + <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> تک"</string> <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string> <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC غیر فعال ہے"</string> <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC فعال ہے"</string> @@ -433,8 +430,7 @@ <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> - <!-- no translation found for manage_notifications_text (8035284146227267681) --> - <skip /> + <string name="manage_notifications_text" msgid="8035284146227267681">"اطلاعات کا نظم کریں"</string> <string name="dnd_suppressing_shade_text" msgid="5179021215370153526">"\'ڈسٹرب نہ کریں\' اطلاعات کو چھپا رہی ہے"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"ابھی شروع کریں"</string> <string name="empty_shade_text" msgid="708135716272867002">"کوئی اطلاعات نہیں ہیں"</string> @@ -633,8 +629,7 @@ <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> <string name="notification_menu_snooze_description" msgid="3653669438131034525">"اطلاع اسنوز کرنے کے اختیارات"</string> - <!-- no translation found for notification_menu_snooze_action (1112254519029621372) --> - <skip /> + <string name="notification_menu_snooze_action" msgid="1112254519029621372">"اسنوز کریں"</string> <string name="snooze_undo" msgid="6074877317002985129">"کالعدم کریں"</string> <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> کیلئے اسنوز کیا گیا"</string> <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030"> diff --git a/packages/SystemUI/res/values/attrs_car.xml b/packages/SystemUI/res/values/attrs_car.xml index 5e4bd79bcc04..335ae4464dd0 100644 --- a/packages/SystemUI/res/values/attrs_car.xml +++ b/packages/SystemUI/res/values/attrs_car.xml @@ -19,6 +19,8 @@ <declare-styleable name="CarFacetButton"> <!-- icon to be rendered (drawable) --> <attr name="icon" format="reference"/> + <!-- icon to be rendered when in selected state --> + <attr name="selectedIcon" format="reference"/> <!-- intent to start when button is click --> <attr name="intent" format="string"/> <!-- intent to start when a long press has happened --> @@ -45,6 +47,12 @@ <attr name="longIntent" format="string"/> <!-- start the intent as a broad cast instead of an activity if true--> <attr name="broadcast" format="boolean"/> + <!-- Alpha value to used when in selected state. Defaults 1f --> + <attr name="selectedAlpha" format="float" /> + <!-- Alpha value to used when in un-selected state. Defaults 0.7f --> + <attr name="unselectedAlpha" format="float" /> + <!-- icon to be rendered when in selected state --> + <attr name="selectedIcon" format="reference"/> </declare-styleable> <!-- Custom attributes to configure hvac values --> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ThreadedRendererCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ThreadedRendererCompat.java new file mode 100644 index 000000000000..bf88a291843d --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ThreadedRendererCompat.java @@ -0,0 +1,33 @@ +/* + * 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.shared.system; + +import android.view.ThreadedRenderer; + +/** + * @see ThreadedRenderer + */ +public class ThreadedRendererCompat { + + public static int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101; + public static int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102; + public static int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103; + + public static void setContextPriority(int priority) { + ThreadedRenderer.setContextPriority(priority); + } +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java index c82c5191b127..9975c413d976 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java @@ -101,6 +101,11 @@ public class TransactionCompat { return this; } + public TransactionCompat setEarlyWakeup() { + mTransaction.setEarlyWakeup(); + return this; + } + public TransactionCompat setColor(SurfaceControlCompat surfaceControl, float[] color) { mTransaction.setColor(surfaceControl.mSurfaceControl, color); return this; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index ce16efbb311f..ff3af17bb61d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -216,8 +216,7 @@ public class KeyguardStatusView extends GridLayout { } public void refreshTime() { - mClockView.setFormat12Hour(Patterns.clockView12); - mClockView.setFormat24Hour(Patterns.clockView24); + mClockView.refresh(); } private void refresh() { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 778e63092150..c39076499d08 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -109,7 +109,11 @@ public class DozeUi implements DozeMachine.Part { switch (newState) { case DOZE_AOD: if (oldState == DOZE_AOD_PAUSED) { + // Whenever turning on the display, it's necessary to push a new frame. + // The display buffers will be empty and need to be filled. mHost.dozeTimeTick(); + // The first frame may arrive when the display isn't ready yet. + mHandler.postDelayed(mHost::dozeTimeTick, 100); } scheduleTimeTick(); break; diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java index 69218365049a..d1d66097d48d 100644 --- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java +++ b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java @@ -27,6 +27,7 @@ import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; @@ -165,7 +166,7 @@ public class FingerprintDialogView extends LinearLayout { title.setSelected(true); final CharSequence subtitleText = mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE); - if (subtitleText == null) { + if (TextUtils.isEmpty(subtitleText)) { subtitle.setVisibility(View.GONE); } else { subtitle.setVisibility(View.VISIBLE); @@ -173,11 +174,11 @@ public class FingerprintDialogView extends LinearLayout { } final CharSequence descriptionText = mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION); - if (descriptionText == null) { - subtitle.setVisibility(View.VISIBLE); + if (TextUtils.isEmpty(descriptionText)) { description.setVisibility(View.GONE); } else { - description.setText(mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION)); + description.setVisibility(View.VISIBLE); + description.setText(descriptionText); } negative.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT)); diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index 3dd6e353c924..bfbba7c1128a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -107,7 +107,7 @@ public class ScreenPinningRequest implements View.OnClickListener { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java index 5f3e2e358306..7285db659f3e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java @@ -42,6 +42,11 @@ public class CarFacetButton extends LinearLayout { /** App packages that are allowed to be used with this widget */ private String[] mFacetPackages; private int mIconResourceId; + /** + * If defined in the xml this will be the icon that's rendered when the button is marked as + * selected + */ + private int mSelectedIconResourceId; private boolean mUseMoreIcon = true; private float mSelectedAlpha = 1f; private float mUnselectedAlpha = 1f; @@ -112,10 +117,9 @@ public class CarFacetButton extends LinearLayout { mIcon.setClickable(false); mIcon.setAlpha(mUnselectedAlpha); mIconResourceId = styledAttributes.getResourceId(R.styleable.CarFacetButton_icon, 0); - if (mIconResourceId == 0) { - throw new RuntimeException("specified icon resource was not found and is required"); - } mIcon.setImageResource(mIconResourceId); + mSelectedIconResourceId = styledAttributes.getResourceId( + R.styleable.CarFacetButton_selectedIcon, mIconResourceId); mMoreIcon = findViewById(R.id.car_nav_button_more_icon); mMoreIcon.setClickable(false); @@ -161,22 +165,10 @@ public class CarFacetButton extends LinearLayout { */ public void setSelected(boolean selected, boolean showMoreIcon) { mSelected = selected; - if (selected) { - if (mUseMoreIcon) { - mMoreIcon.setVisibility(showMoreIcon ? VISIBLE : GONE); - } - mIcon.setAlpha(mSelectedAlpha); - } else { - mMoreIcon.setVisibility(GONE); - mIcon.setAlpha(mUnselectedAlpha); - } - } - - public void setIcon(Drawable d) { - if (d != null) { - mIcon.setImageDrawable(d); - } else { - mIcon.setImageResource(mIconResourceId); + mIcon.setAlpha(mSelected ? mSelectedAlpha : mUnselectedAlpha); + mIcon.setImageResource(mSelected ? mSelectedIconResourceId : mIconResourceId); + if (mUseMoreIcon) { + mMoreIcon.setVisibility(showMoreIcon ? VISIBLE : GONE); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java index e73b1736f33a..b2cef16277f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java @@ -25,7 +25,9 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.keyguard.AlphaOptimizedImageButton; +import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.StatusBarIconController; /** * A custom navigation bar for the automotive use case. @@ -52,6 +54,17 @@ class CarNavigationBarView extends LinearLayout { if (mNotificationsButton != null) { mNotificationsButton.setOnClickListener(this::onNotificationsClick); } + View mStatusIcons = findViewById(R.id.statusIcons); + if (mStatusIcons != null) { + // Attach the controllers for Status icons such as wifi and bluetooth if the standard + // container is in the view. + StatusBarIconController.DarkIconManager mDarkIconManager = + new StatusBarIconController.DarkIconManager( + mStatusIcons.findViewById(R.id.statusIcons)); + mDarkIconManager.setShouldLog(true); + Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); + } + } void setStatusBar(CarStatusBar carStatusBar) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java index 0cdaec1432c7..e248db4b2a06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; import android.util.AttributeSet; +import android.util.Log; import android.widget.ImageView; import com.android.systemui.R; @@ -17,23 +18,34 @@ import java.net.URISyntaxException; */ public class CarNavigationButton extends com.android.keyguard.AlphaOptimizedImageButton { - private static final float SELECTED_ALPHA = 1; - private static final float UNSELECTED_ALPHA = 0.7f; - + private static final String TAG = "CarNavigationButton"; private Context mContext; - private String mIntent = null; - private String mLongIntent = null; - private boolean mBroadcastIntent = false; + private String mIntent; + private String mLongIntent; + private boolean mBroadcastIntent; private boolean mSelected = false; + private float mSelectedAlpha; + private float mUnselectedAlpha; + private int mSelectedIconResourceId; + private int mIconResourceId; public CarNavigationButton(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; - TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CarNavigationButton); + TypedArray typedArray = context.obtainStyledAttributes( + attrs, R.styleable.CarNavigationButton); mIntent = typedArray.getString(R.styleable.CarNavigationButton_intent); mLongIntent = typedArray.getString(R.styleable.CarNavigationButton_longIntent); mBroadcastIntent = typedArray.getBoolean(R.styleable.CarNavigationButton_broadcast, false); + mSelectedAlpha = typedArray.getFloat( + R.styleable.CarNavigationButton_selectedAlpha, mSelectedAlpha); + mUnselectedAlpha = typedArray.getFloat( + R.styleable.CarNavigationButton_unselectedAlpha, mUnselectedAlpha); + mIconResourceId = typedArray.getResourceId( + com.android.internal.R.styleable.ImageView_src, 0); + mSelectedIconResourceId = typedArray.getResourceId( + R.styleable.CarNavigationButton_selectedIcon, mIconResourceId); } @@ -45,17 +57,20 @@ public class CarNavigationButton extends com.android.keyguard.AlphaOptimizedImag public void onFinishInflate() { super.onFinishInflate(); setScaleType(ImageView.ScaleType.CENTER); - setAlpha(UNSELECTED_ALPHA); + setAlpha(mUnselectedAlpha); try { if (mIntent != null) { final Intent intent = Intent.parseUri(mIntent, Intent.URI_INTENT_SCHEME); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); setOnClickListener(v -> { - if (mBroadcastIntent) { - mContext.sendBroadcast(intent); - return; + try { + if (mBroadcastIntent) { + mContext.sendBroadcast(intent); + return; + } + mContext.startActivity(intent); + } catch (Exception e) { + Log.e(TAG, "Failed to launch intent", e); } - mContext.startActivity(intent); }); } } catch (URISyntaxException e) { @@ -65,9 +80,13 @@ public class CarNavigationButton extends com.android.keyguard.AlphaOptimizedImag try { if (mLongIntent != null) { final Intent intent = Intent.parseUri(mLongIntent, Intent.URI_INTENT_SCHEME); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); setOnLongClickListener(v -> { - mContext.startActivity(intent); + try { + mContext.startActivity(intent); + } catch (Exception e) { + Log.e(TAG, "Failed to launch intent", e); + } + // consume event either way return true; }); } @@ -82,6 +101,7 @@ public class CarNavigationButton extends com.android.keyguard.AlphaOptimizedImag public void setSelected(boolean selected) { super.setSelected(selected); mSelected = selected; - setAlpha(mSelected ? SELECTED_ALPHA : UNSELECTED_ALPHA); + setAlpha(mSelected ? mSelectedAlpha : mUnselectedAlpha); + setImageResource(mSelected ? mSelectedIconResourceId : mIconResourceId); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java index 3bbfe3c1062c..b8bce95190f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java @@ -238,6 +238,7 @@ public class ActivityLaunchAnimator { t.deferTransactionUntilSurface(app.leash, systemUiSurface, systemUiSurface.getNextFrameNumber()); } + t.setEarlyWakeup(); t.apply(); } diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java index e18140984f0e..a901e88219a5 100644 --- a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java +++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java @@ -23,7 +23,7 @@ import android.os.Handler; */ public class DelayedWakeLock implements WakeLock { - private static final long RELEASE_DELAY_MS = 240; + private static final long RELEASE_DELAY_MS = 140; private final Handler mHandler; private final WakeLock mInner; diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 934ad882a635..595a1d9ec96b 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -422,6 +422,16 @@ message WifiLog { // Indicates the number of times a scan request from an external background app was throttled. optional int32 num_external_background_app_oneshot_scan_requests_throttled = 106; + + // WifiLastResortWatchdog time milliseconds delta between trigger and first connection success + optional int64 watchdog_trigger_to_connection_success_duration_ms = 107 [default = -1]; + + // The number of times wifi experienced failures after watchdog has already been triggered and is + // waiting for a connection success + optional int64 watchdog_total_connection_failure_count_after_trigger = 108; + + // Number of times DFS channel scans are requested in single scan requests. + optional int32 num_oneshot_has_dfs_channel_scans = 109; } // Information that gets logged for every WiFi connection. @@ -1271,9 +1281,16 @@ message WifiWakeStats { // Start time of session in milliseconds. optional int64 start_time_millis = 1; - // The number of networks the lock was initialized with at start. + // The number of networks the lock was provided with at start. optional int32 locked_networks_at_start = 2; + // The number of networks in the lock at the time of the initialize event. Only valid if + // initialize_event is recorded. + optional int32 locked_networks_at_initialize = 6; + + // Event for fully initializing the WakeupLock (i.e. WakeupLock is "locked"). + optional Event initialize_event = 7; + // Event for unlocking the WakeupLock. Does not occur if lock was initialized with 0 networks. optional Event unlock_event = 3; @@ -1289,4 +1306,10 @@ message WifiWakeStats { // Session information for every Wifi Wake session (up to a maximum of 10). repeated Session sessions = 2; + + // Number of ignored calls to start (due to WakeupController already being active). + optional int32 num_ignored_starts = 3; + + // Number of Wifi Wake sessions that have recorded wakeup events. + optional int32 num_wakeups = 4; } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index a1ef1ed9e9bb..59cb13562764 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -934,7 +934,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Used only for testing. // TODO: Delete this and either: - // 1. Give Fake SettingsProvider the ability to send settings change notifications (requires + // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires // changing ContentResolver to make registerContentObserver non-final). // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it // by subclassing SettingsObserver. @@ -943,6 +943,12 @@ public class ConnectivityService extends IConnectivityManager.Stub mHandler.sendEmptyMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON); } + // See FakeSettingsProvider comment above. + @VisibleForTesting + void updatePrivateDnsSettings() { + mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED); + } + private void handleMobileDataAlwaysOn() { final boolean enable = toBool(Settings.Global.getInt( mContext.getContentResolver(), Settings.Global.MOBILE_DATA_ALWAYS_ON, 1)); @@ -972,8 +978,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void registerPrivateDnsSettingsCallbacks() { - for (Uri u : DnsManager.getPrivateDnsSettingsUris()) { - mSettingsObserver.observe(u, EVENT_PRIVATE_DNS_SETTINGS_CHANGED); + for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) { + mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED); } } @@ -1026,8 +1032,12 @@ public class ConnectivityService extends IConnectivityManager.Stub if (network == null) { return null; } + return getNetworkAgentInfoForNetId(network.netId); + } + + private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) { synchronized (mNetworkForNetId) { - return mNetworkForNetId.get(network.netId); + return mNetworkForNetId.get(netId); } } @@ -1167,9 +1177,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } NetworkAgentInfo nai; if (vpnNetId != NETID_UNSET) { - synchronized (mNetworkForNetId) { - nai = mNetworkForNetId.get(vpnNetId); - } + nai = getNetworkAgentInfoForNetId(vpnNetId); if (nai != null) return nai.network; } nai = getDefaultNetwork(); @@ -2155,41 +2163,21 @@ public class ConnectivityService extends IConnectivityManager.Stub default: return false; case NetworkMonitor.EVENT_NETWORK_TESTED: { - final NetworkAgentInfo nai; - synchronized (mNetworkForNetId) { - nai = mNetworkForNetId.get(msg.arg2); - } + final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); if (nai == null) break; final boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID); final boolean wasValidated = nai.lastValidated; final boolean wasDefault = isDefaultNetwork(nai); - final PrivateDnsConfig privateDnsCfg = (msg.obj instanceof PrivateDnsConfig) - ? (PrivateDnsConfig) msg.obj : null; final String redirectUrl = (msg.obj instanceof String) ? (String) msg.obj : ""; - final boolean reevaluationRequired; - final String logMsg; - if (valid) { - reevaluationRequired = updatePrivateDns(nai, privateDnsCfg); - logMsg = (DBG && (privateDnsCfg != null)) - ? " with " + privateDnsCfg.toString() : ""; - } else { - reevaluationRequired = false; - logMsg = (DBG && !TextUtils.isEmpty(redirectUrl)) - ? " with redirect to " + redirectUrl : ""; - } if (DBG) { + final String logMsg = !TextUtils.isEmpty(redirectUrl) + ? " with redirect to " + redirectUrl + : ""; log(nai.name() + " validation " + (valid ? "passed" : "failed") + logMsg); } - // If there is a change in Private DNS configuration, - // trigger reevaluation of the network to test it. - if (reevaluationRequired) { - nai.networkMonitor.sendMessage( - NetworkMonitor.CMD_FORCE_REEVALUATION, Process.SYSTEM_UID); - break; - } if (valid != nai.lastValidated) { if (wasDefault) { metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity( @@ -2218,10 +2206,7 @@ public class ConnectivityService extends IConnectivityManager.Stub case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: { final int netId = msg.arg2; final boolean visible = toBool(msg.arg1); - final NetworkAgentInfo nai; - synchronized (mNetworkForNetId) { - nai = mNetworkForNetId.get(netId); - } + final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId); // If captive portal status has changed, update capabilities or disconnect. if (nai != null && (visible != nai.lastCaptivePortalDetected)) { final int oldScore = nai.getCurrentScore(); @@ -2252,18 +2237,10 @@ public class ConnectivityService extends IConnectivityManager.Stub break; } case NetworkMonitor.EVENT_PRIVATE_DNS_CONFIG_RESOLVED: { - final NetworkAgentInfo nai; - synchronized (mNetworkForNetId) { - nai = mNetworkForNetId.get(msg.arg2); - } + final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); if (nai == null) break; - final PrivateDnsConfig cfg = (PrivateDnsConfig) msg.obj; - final boolean reevaluationRequired = updatePrivateDns(nai, cfg); - if (nai.lastValidated && reevaluationRequired) { - nai.networkMonitor.sendMessage( - NetworkMonitor.CMD_FORCE_REEVALUATION, Process.SYSTEM_UID); - } + updatePrivateDns(nai, (PrivateDnsConfig) msg.obj); break; } } @@ -2301,61 +2278,38 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + private boolean networkRequiresValidation(NetworkAgentInfo nai) { + return NetworkMonitor.isValidationRequired( + mDefaultRequest.networkCapabilities, nai.networkCapabilities); + } + private void handlePrivateDnsSettingsChanged() { final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { - // Private DNS only ever applies to networks that might provide - // Internet access and therefore also require validation. - if (!NetworkMonitor.isValidationRequired( - mDefaultRequest.networkCapabilities, nai.networkCapabilities)) { - continue; - } - - // Notify the NetworkMonitor thread in case it needs to cancel or - // schedule DNS resolutions. If a DNS resolution is required the - // result will be sent back to us. - nai.networkMonitor.notifyPrivateDnsSettingsChanged(cfg); - - if (!cfg.inStrictMode()) { - // No strict mode hostname DNS resolution needed, so just update - // DNS settings directly. In opportunistic and "off" modes this - // just reprograms netd with the network-supplied DNS servers - // (and of course the boolean of whether or not to attempt TLS). - // - // TODO: Consider code flow parity with strict mode, i.e. having - // NetworkMonitor relay the PrivateDnsConfig back to us and then - // performing this call at that time. - updatePrivateDns(nai, cfg); - } + handlePerNetworkPrivateDnsConfig(nai, cfg); } } - private boolean updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { - final boolean reevaluationRequired = true; - final boolean dontReevaluate = false; + private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) { + // Private DNS only ever applies to networks that might provide + // Internet access and therefore also require validation. + if (!networkRequiresValidation(nai)) return; - final PrivateDnsConfig oldCfg = mDnsManager.updatePrivateDns(nai.network, newCfg); - updateDnses(nai.linkProperties, null, nai.network.netId); + // Notify the NetworkMonitor thread in case it needs to cancel or + // schedule DNS resolutions. If a DNS resolution is required the + // result will be sent back to us. + nai.networkMonitor.notifyPrivateDnsSettingsChanged(cfg); - if (newCfg == null) { - if (oldCfg == null) return dontReevaluate; - return oldCfg.useTls ? reevaluationRequired : dontReevaluate; - } - - if (oldCfg == null) { - return newCfg.useTls ? reevaluationRequired : dontReevaluate; - } - - if (oldCfg.useTls != newCfg.useTls) { - return reevaluationRequired; - } - - if (newCfg.inStrictMode() && !Objects.equals(oldCfg.hostname, newCfg.hostname)) { - return reevaluationRequired; - } + // With Private DNS bypass support, we can proceed to update the + // Private DNS config immediately, even if we're in strict mode + // and have not yet resolved the provider name into a set of IPs. + updatePrivateDns(nai, cfg); + } - return dontReevaluate; + private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { + mDnsManager.updatePrivateDns(nai.network, newCfg); + updateDnses(nai.linkProperties, null, nai.network.netId); } private void updateLingerState(NetworkAgentInfo nai, long now) { @@ -3300,7 +3254,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) { return; } - nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid); + nai.networkMonitor.forceReevaluation(uid); } private ProxyInfo getDefaultProxy() { @@ -4919,7 +4873,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) { - if (mNetworkForNetId.get(nai.network.netId) != nai) { + if (getNetworkAgentInfoForNetId(nai.network.netId) != nai) { // Ignore updates for disconnected networks return; } @@ -5495,6 +5449,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) { networkAgent.everConnected = true; + handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig()); updateLinkProperties(networkAgent, null); notifyIfacesChangedForNetworkStats(); @@ -5911,4 +5866,4 @@ public class ConnectivityService extends IConnectivityManager.Stub pw.println(" Get airplane mode."); } } -}
\ No newline at end of file +} diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index 45c9a711e8c5..48bb409e8975 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -219,7 +219,7 @@ option java_package com.android.server # DisplayManagerService.java # --------------------------- # Auto-brightness adjustments by the user. -35000 auto_brightness_adj (old_adj|5),(old_lux|5),(old_brightness|5),(old_gamma|5),(new_adj|5),(new_lux|5),(new_brightness|5),(new_gamma|5) +35000 auto_brightness_adj (old_lux|5),(old_brightness|5),(new_lux|5),(new_brightness|5) # --------------------------- # ConnectivityService.java diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index 33f77697f88c..80d7ac931111 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -128,6 +128,30 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } }; + public static final class Lifecycle extends SystemService { + private final NetworkScoreService mService; + + public Lifecycle(Context context) { + super(context); + mService = new NetworkScoreService(context); + } + + @Override + public void onStart() { + Log.i(TAG, "Registering " + Context.NETWORK_SCORE_SERVICE); + publishBinderService(Context.NETWORK_SCORE_SERVICE, mService); + } + + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_SYSTEM_SERVICES_READY) { + mService.systemReady(); + } else if (phase == PHASE_BOOT_COMPLETED) { + mService.systemRunning(); + } + } + } + /** * Clears scores when the active scorer package is no longer valid and * manages the service connection. diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 4a8bc8745012..fac3f92463af 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -16,7 +16,6 @@ package com.android.server.am; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; @@ -44,7 +43,6 @@ import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.WindowConfiguration; import android.graphics.Point; -import android.graphics.Rect; import android.util.IntArray; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -702,57 +700,52 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } /** - * @return the stack currently above the home stack. Can be null if there is no home stack, or - * the home stack is already on top. + * @return the stack currently above the {@param stack}. Can be null if the {@param stack} is + * already top-most. */ - ActivityStack getStackAboveHome() { - if (mHomeStack == null) { - // Skip if there is no home stack - return null; - } - - final int stackIndex = mStacks.indexOf(mHomeStack) + 1; + ActivityStack getStackAbove(ActivityStack stack) { + final int stackIndex = mStacks.indexOf(stack) + 1; return (stackIndex < mStacks.size()) ? mStacks.get(stackIndex) : null; } /** - * Adjusts the home stack behind the last visible stack in the display if necessary. Generally - * used in conjunction with {@link #moveHomeStackBehindStack}. + * Adjusts the {@param stack} behind the last visible stack in the display if necessary. + * Generally used in conjunction with {@link #moveStackBehindStack}. */ - void moveHomeStackBehindBottomMostVisibleStack() { - if (mHomeStack == null || mHomeStack.shouldBeVisible(null)) { - // Skip if there is no home stack, or if it is already visible + void moveStackBehindBottomMostVisibleStack(ActivityStack stack) { + if (stack.shouldBeVisible(null)) { + // Skip if the stack is already visible return; } - // Move the home stack to the bottom to not affect the following visibility checks - positionChildAtBottom(mHomeStack); + // Move the stack to the bottom to not affect the following visibility checks + positionChildAtBottom(stack); - // Find the next position where the homes stack should be placed + // Find the next position where the stack should be placed final int numStacks = mStacks.size(); for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) { - final ActivityStack stack = mStacks.get(stackNdx); - if (stack == mHomeStack) { + final ActivityStack s = mStacks.get(stackNdx); + if (s == stack) { continue; } - final int winMode = stack.getWindowingMode(); + final int winMode = s.getWindowingMode(); final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN || winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; - if (stack.shouldBeVisible(null) && isValidWindowingMode) { - // Move the home stack to behind this stack - positionChildAt(mHomeStack, Math.max(0, stackNdx - 1)); + if (s.shouldBeVisible(null) && isValidWindowingMode) { + // Move the provided stack to behind this stack + positionChildAt(stack, Math.max(0, stackNdx - 1)); break; } } } /** - * Moves the home stack behind the given {@param stack} if possible. If {@param stack} is not - * currently in the display, then then the home stack is moved to the back. Generally used in - * conjunction with {@link #moveHomeStackBehindBottomMostVisibleStack}. + * Moves the {@param stack} behind the given {@param behindStack} if possible. If + * {@param behindStack} is not currently in the display, then then the stack is moved to the + * back. Generally used in conjunction with {@link #moveStackBehindBottomMostVisibleStack}. */ - void moveHomeStackBehindStack(ActivityStack behindStack) { - if (behindStack == null || behindStack == mHomeStack) { + void moveStackBehindStack(ActivityStack stack, ActivityStack behindStack) { + if (behindStack == null || behindStack == stack) { return; } @@ -760,11 +753,11 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> // list, so we need to adjust the insertion index to account for the removed index // TODO: Remove this logic when WindowContainer.positionChildAt() is updated to adjust the // position internally - final int homeStackIndex = mStacks.indexOf(mHomeStack); + final int stackIndex = mStacks.indexOf(stack); final int behindStackIndex = mStacks.indexOf(behindStack); - final int insertIndex = homeStackIndex <= behindStackIndex + final int insertIndex = stackIndex <= behindStackIndex ? behindStackIndex - 1 : behindStackIndex; - positionChildAt(mHomeStack, Math.max(0, insertIndex)); + positionChildAt(stack, Math.max(0, insertIndex)); } boolean isSleeping() { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index adf3480de8d2..75bad46a5cfc 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -39,6 +39,7 @@ import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE; import static android.app.ActivityThread.PROC_START_SEQ_IDENT; import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE; import static android.app.AppOpsManager.OP_NONE; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; @@ -205,8 +206,8 @@ import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; -import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION; -import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_HOME_IN_PLACE; +import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; +import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -5249,8 +5250,8 @@ public class ActivityManagerService extends IActivityManager.Stub try { synchronized (this) { mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition - ? REORDER_MOVE_HOME_TO_ORIGINAL_POSITION - : REORDER_KEEP_HOME_IN_PLACE); + ? REORDER_MOVE_TO_ORIGINAL_POSITION + : REORDER_KEEP_IN_PLACE); } } finally { Binder.restoreCallingIdentity(origId); @@ -12958,9 +12959,13 @@ public class ActivityManagerService extends IActivityManager.Stub } catch (RemoteException exc) { // Ignore. } + return isBackgroundRestrictedNoCheck(callingUid, packageName); + } + + boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) { final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, - callingUid, packageName); - return (mode != AppOpsManager.MODE_ALLOWED); + uid, packageName); + return mode != AppOpsManager.MODE_ALLOWED; } @Override @@ -21055,6 +21060,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } + final String action = intent.getAction(); BroadcastOptions brOptions = null; if (bOptions != null) { brOptions = new BroadcastOptions(bOptions); @@ -21075,11 +21081,16 @@ public class ActivityManagerService extends IActivityManager.Stub throw new SecurityException(msg); } } + if (brOptions.isDontSendToRestrictedApps() + && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) { + Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage + + " has background restrictions"); + return ActivityManager.START_CANCELED; + } } // Verify that protected broadcasts are only being sent by system code, // and that system code is only sending protected broadcasts. - final String action = intent.getAction(); final boolean isProtectedBroadcast; try { isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action); @@ -21901,8 +21912,6 @@ public class ActivityManagerService extends IActivityManager.Stub "com.android.frameworks.locationtests", "com.android.frameworks.coretests.privacy", "com.android.settings.ui", - "com.android.perftests.core", - "com.android.perftests.multiuser", }; public boolean startInstrumentation(ComponentName className, diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java index ad25099814d2..17eeb5b2f4f5 100644 --- a/services/core/java/com/android/server/am/RecentsAnimation.java +++ b/services/core/java/com/android/server/am/RecentsAnimation.java @@ -18,19 +18,20 @@ package com.android.server.am; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.WindowManager.TRANSIT_NONE; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; -import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_HOME_IN_PLACE; -import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION; -import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_TOP; +import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; +import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; +import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP; import android.app.ActivityOptions; import android.content.ComponentName; import android.content.Intent; -import android.os.Handler; import android.os.RemoteException; import android.os.Trace; import android.util.Slog; @@ -51,16 +52,20 @@ class RecentsAnimation implements RecentsAnimationCallbacks { private final ActivityStartController mActivityStartController; private final WindowManagerService mWindowManager; private final UserController mUserController; + private final ActivityDisplay mDefaultDisplay; private final int mCallingPid; - // The stack to restore the home stack behind when the animation is finished - private ActivityStack mRestoreHomeBehindStack; + private int mTargetActivityType; + + // The stack to restore the target stack behind when the animation is finished + private ActivityStack mRestoreTargetBehindStack; RecentsAnimation(ActivityManagerService am, ActivityStackSupervisor stackSupervisor, ActivityStartController activityStartController, WindowManagerService wm, UserController userController, int callingPid) { mService = am; mStackSupervisor = stackSupervisor; + mDefaultDisplay = stackSupervisor.getDefaultDisplay(); mActivityStartController = activityStartController; mWindowManager = wm; mUserController = userController; @@ -76,23 +81,31 @@ class RecentsAnimation implements RecentsAnimationCallbacks { return; } - // If the existing home activity is already on top, then cancel - ActivityRecord homeActivity = mStackSupervisor.getHomeActivity(); - final boolean hasExistingHomeActivity = homeActivity != null; - if (hasExistingHomeActivity) { - final ActivityDisplay display = homeActivity.getDisplay(); - mRestoreHomeBehindStack = display.getStackAboveHome(); - if (mRestoreHomeBehindStack == null) { + // If the activity is associated with the recents stack, then try and get that first + mTargetActivityType = intent.getComponent() != null + && recentsComponent.equals(intent.getComponent()) + ? ACTIVITY_TYPE_RECENTS + : ACTIVITY_TYPE_HOME; + final ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, + mTargetActivityType); + ActivityRecord targetActivity = targetStack != null + ? targetStack.getTopActivity() + : null; + final boolean hasExistingActivity = targetActivity != null; + if (hasExistingActivity) { + final ActivityDisplay display = targetActivity.getDisplay(); + mRestoreTargetBehindStack = display.getStackAbove(targetStack); + if (mRestoreTargetBehindStack == null) { notifyAnimationCancelBeforeStart(recentsAnimationRunner); return; } } - // Send launch hint if we are actually launching home. If it's already visible (shouldn't - // happen in general) we don't need to send it. - if (homeActivity == null || !homeActivity.visible) { + // Send launch hint if we are actually launching the target. If it's already visible + // (shouldn't happen in general) we don't need to send it. + if (targetActivity == null || !targetActivity.visible) { mStackSupervisor.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */, - homeActivity); + targetActivity); } mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(); @@ -102,48 +115,49 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mWindowManager.deferSurfaceLayout(); try { final ActivityDisplay display; - if (hasExistingHomeActivity) { - // Move the home activity into place for the animation if it is not already top most - display = homeActivity.getDisplay(); - display.moveHomeStackBehindBottomMostVisibleStack(); + if (hasExistingActivity) { + // Move the recents activity into place for the animation if it is not top most + display = targetActivity.getDisplay(); + display.moveStackBehindBottomMostVisibleStack(targetStack); } else { - // No home activity - final ActivityOptions opts = ActivityOptions.makeBasic(); - opts.setLaunchActivityType(ACTIVITY_TYPE_HOME); - opts.setAvoidMoveToFront(); + // No recents activity + ActivityOptions options = ActivityOptions.makeBasic(); + options.setLaunchActivityType(mTargetActivityType); + options.setAvoidMoveToFront(); intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION); mActivityStartController - .obtainStarter(intent, "startRecentsActivity_noHomeActivity") + .obtainStarter(intent, "startRecentsActivity_noTargetActivity") .setCallingUid(recentsUid) .setCallingPackage(recentsComponent.getPackageName()) - .setActivityOptions(SafeActivityOptions.fromBundle(opts.toBundle())) + .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle())) .setMayWait(mUserController.getCurrentUserId()) .execute(); mWindowManager.prepareAppTransition(TRANSIT_NONE, false); - homeActivity = mStackSupervisor.getHomeActivity(); - display = homeActivity.getDisplay(); + targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, + mTargetActivityType).getTopActivity(); + display = targetActivity.getDisplay(); // TODO: Maybe wait for app to draw in this particular case? } - // Mark the home activity as launch-behind to bump its visibility for the + // Mark the target activity as launch-behind to bump its visibility for the // duration of the gesture that is driven by the recents component - homeActivity.mLaunchTaskBehind = true; + targetActivity.mLaunchTaskBehind = true; // Fetch all the surface controls and pass them to the client to get the animation // started - mWindowManager.cancelRecentsAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); - mWindowManager.initializeRecentsAnimation(recentsAnimationRunner, this, - display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); + mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); + mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner, + this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); // If we updated the launch-behind state, update the visibility of the activities after // we fetch the visible tasks to be controlled by the animation mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT, - homeActivity); + targetActivity); } finally { mWindowManager.continueSurfaceLayout(); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); @@ -155,9 +169,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { synchronized (mService) { if (mWindowManager.getRecentsAnimationController() == null) return; - // Just to be sure end the launch hint in case home was never launched. However, if - // we're keeping home and making it visible, we can leave it on. - if (reorderMode != REORDER_KEEP_HOME_IN_PLACE) { + // Just to be sure end the launch hint in case the target activity was never launched. + // However, if we're keeping the activity and making it visible, we can leave it on. + if (reorderMode != REORDER_KEEP_IN_PLACE) { mStackSupervisor.sendPowerHintForLaunchEndIfNeeded(); } @@ -170,26 +184,27 @@ class RecentsAnimation implements RecentsAnimationCallbacks { try { mWindowManager.cleanupRecentsAnimation(reorderMode); - final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity(); - if (homeActivity == null) { + final ActivityStack targetStack = mDefaultDisplay.getStack( + WINDOWING_MODE_UNDEFINED, mTargetActivityType); + final ActivityRecord targetActivity = targetStack.getTopActivity(); + if (targetActivity == null) { return; } // Restore the launched-behind state - homeActivity.mLaunchTaskBehind = false; - - if (reorderMode == REORDER_MOVE_HOME_TO_TOP) { - // Bring the home stack to the front - final ActivityStack homeStack = homeActivity.getStack(); - mStackSupervisor.mNoAnimActivities.add(homeActivity); - homeStack.moveToFront("RecentsAnimation.onAnimationFinished()"); - } else if (reorderMode == REORDER_MOVE_HOME_TO_ORIGINAL_POSITION){ - // Restore the home stack to its previous position - final ActivityDisplay display = homeActivity.getDisplay(); - display.moveHomeStackBehindStack(mRestoreHomeBehindStack); + targetActivity.mLaunchTaskBehind = false; + + if (reorderMode == REORDER_MOVE_TO_TOP) { + // Bring the target stack to the front + mStackSupervisor.mNoAnimActivities.add(targetActivity); + targetStack.moveToFront("RecentsAnimation.onAnimationFinished()"); + } else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){ + // Restore the target stack to its previous position + final ActivityDisplay display = targetActivity.getDisplay(); + display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack); } else { - // Keep home stack in place, nothing changes, so ignore the transition logic - // below + // Keep target stack in place, nothing changes, so ignore the transition + // logic below return; } @@ -202,8 +217,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mWindowManager.executeAppTransition(); // After reordering the stacks, reset the minimized state. At this point, either - // home is now top-most and we will stay minimized (if in split-screen), or we - // will have returned to the app, and the minimized state should be reset + // the target activity is now top-most and we will stay minimized (if in + // split-screen), or we will have returned to the app, and the minimized state + // should be reset mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */); } finally { mWindowManager.continueSurfaceLayout(); diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java index 55798491cdef..2a361a02d7d2 100644 --- a/services/core/java/com/android/server/connectivity/DnsManager.java +++ b/services/core/java/com/android/server/connectivity/DnsManager.java @@ -61,6 +61,51 @@ import java.util.StringJoiner; * This class it NOT designed for concurrent access. Furthermore, all non-static * methods MUST be called from ConnectivityService's thread. * + * [ Private DNS ] + * The code handling Private DNS is spread across several components, but this + * seems like the least bad place to collect all the observations. + * + * Private DNS handling and updating occurs in response to several different + * events. Each is described here with its corresponding intended handling. + * + * [A] Event: A new network comes up. + * Mechanics: + * [1] ConnectivityService gets notifications from NetworkAgents. + * [2] in updateNetworkInfo(), the first time the NetworkAgent goes into + * into CONNECTED state, the Private DNS configuration is retrieved, + * programmed, and strict mode hostname resolution (if applicable) is + * enqueued in NetworkAgent's NetworkMonitor, via a call to + * handlePerNetworkPrivateDnsConfig(). + * [3] Re-resolution of strict mode hostnames that fail to return any + * IP addresses happens inside NetworkMonitor; it sends itself a + * delayed CMD_EVALUATE_PRIVATE_DNS message in a simple backoff + * schedule. + * [4] Successfully resolved hostnames are sent to ConnectivityService + * inside an EVENT_PRIVATE_DNS_CONFIG_RESOLVED message. The resolved + * IP addresses are programmed into netd via: + * + * updatePrivateDns() -> updateDnses() + * + * both of which make calls into DnsManager. + * [5] Upon a successful hostname resolution NetworkMonitor initiates a + * validation attempt in the form of a lookup for a one-time hostname + * that uses Private DNS. + * + * [B] Event: Private DNS settings are changed. + * Mechanics: + * [1] ConnectivityService gets notifications from its SettingsObserver. + * [2] handlePrivateDnsSettingsChanged() is called, which calls + * handlePerNetworkPrivateDnsConfig() and the process proceeds + * as if from A.3 above. + * + * [C] Event: An application calls ConnectivityManager#reportBadNetwork(). + * Mechanics: + * [1] NetworkMonitor is notified and initiates a reevaluation, which + * always bypasses Private DNS. + * [2] Once completed, NetworkMonitor checks if strict mode is in operation + * and if so enqueues another evaluation of Private DNS, as if from + * step A.5 above. + * * @hide */ public class DnsManager { diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 8a2e71c1fba8..284538342a72 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -34,6 +34,7 @@ import android.net.NetworkRequest; import android.net.ProxyInfo; import android.net.TrafficStats; import android.net.Uri; +import android.net.dns.ResolvUtil; import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.metrics.ValidationProbeEvent; @@ -64,6 +65,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import com.android.server.connectivity.DnsManager.PrivateDnsConfig; import java.io.IOException; import java.net.HttpURLConnection; @@ -77,6 +79,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Random; +import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -165,7 +168,7 @@ public class NetworkMonitor extends StateMachine { * Force evaluation even if it has succeeded in the past. * arg1 = UID responsible for requesting this reeval. Will be billed for data. */ - public static final int CMD_FORCE_REEVALUATION = BASE + 8; + private static final int CMD_FORCE_REEVALUATION = BASE + 8; /** * Message to self indicating captive portal app finished. @@ -205,9 +208,15 @@ public class NetworkMonitor extends StateMachine { * Private DNS. If a DNS resolution is required, e.g. for DNS-over-TLS in * strict mode, then an event is sent back to ConnectivityService with the * result of the resolution attempt. + * + * A separate message is used to trigger (re)evaluation of the Private DNS + * configuration, so that the message can be handled as needed in different + * states, including being ignored until after an ongoing captive portal + * validation phase is completed. */ private static final int CMD_PRIVATE_DNS_SETTINGS_CHANGED = BASE + 13; public static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = BASE + 14; + private static final int CMD_EVALUATE_PRIVATE_DNS = BASE + 15; // Start mReevaluateDelayMs at this value and double. private static final int INITIAL_REEVALUATE_DELAY_MS = 1000; @@ -215,6 +224,7 @@ public class NetworkMonitor extends StateMachine { // Before network has been evaluated this many times, ignore repeated reevaluate requests. private static final int IGNORE_REEVALUATE_ATTEMPTS = 5; private int mReevaluateToken = 0; + private static final int NO_UID = 0; private static final int INVALID_UID = -1; private int mUidResponsibleForReeval = INVALID_UID; // Stop blaming UID that requested re-evaluation after this many attempts. @@ -224,6 +234,8 @@ public class NetworkMonitor extends StateMachine { private static final int NUM_VALIDATION_LOG_LINES = 20; + private String mPrivateDnsProviderHostname = ""; + public static boolean isValidationRequired( NetworkCapabilities dfltNetCap, NetworkCapabilities nc) { // TODO: Consider requiring validation for DUN networks. @@ -261,13 +273,12 @@ public class NetworkMonitor extends StateMachine { public boolean systemReady = false; - private DnsManager.PrivateDnsConfig mPrivateDnsCfg = null; - private final State mDefaultState = new DefaultState(); private final State mValidatedState = new ValidatedState(); private final State mMaybeNotifyState = new MaybeNotifyState(); private final State mEvaluatingState = new EvaluatingState(); private final State mCaptivePortalState = new CaptivePortalState(); + private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState(); private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null; @@ -293,6 +304,10 @@ public class NetworkMonitor extends StateMachine { // Add suffix indicating which NetworkMonitor we're talking about. super(TAG + networkAgentInfo.name()); + // Logs with a tag of the form given just above, e.g. + // <timestamp> 862 2402 D NetworkMonitor/NetworkAgentInfo [WIFI () - 100]: ... + setDbg(VDBG); + mContext = context; mMetricsLog = logger; mConnectivityServiceHandler = handler; @@ -305,10 +320,11 @@ public class NetworkMonitor extends StateMachine { mDefaultRequest = defaultRequest; addState(mDefaultState); - addState(mValidatedState, mDefaultState); addState(mMaybeNotifyState, mDefaultState); addState(mEvaluatingState, mMaybeNotifyState); addState(mCaptivePortalState, mMaybeNotifyState); + addState(mEvaluatingPrivateDnsState, mDefaultState); + addState(mValidatedState, mDefaultState); setInitialState(mDefaultState); mIsCaptivePortalCheckEnabled = getIsCaptivePortalCheckEnabled(); @@ -321,6 +337,17 @@ public class NetworkMonitor extends StateMachine { start(); } + public void forceReevaluation(int responsibleUid) { + sendMessage(CMD_FORCE_REEVALUATION, responsibleUid, 0); + } + + public void notifyPrivateDnsSettingsChanged(PrivateDnsConfig newCfg) { + // Cancel any outstanding resolutions. + removeMessages(CMD_PRIVATE_DNS_SETTINGS_CHANGED); + // Send the update to the proper thread. + sendMessage(CMD_PRIVATE_DNS_SETTINGS_CHANGED, newCfg); + } + @Override protected void log(String s) { if (DBG) Log.d(TAG + "/" + mNetworkAgentInfo.name(), s); @@ -349,6 +376,12 @@ public class NetworkMonitor extends StateMachine { mDefaultRequest.networkCapabilities, mNetworkAgentInfo.networkCapabilities); } + + private void notifyNetworkTestResultInvalid(Object obj) { + mConnectivityServiceHandler.sendMessage(obtainMessage( + EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetId, obj)); + } + // DefaultState is the parent of all States. It exists only to handle CMD_* messages but // does not entail any real state (hence no enter() or exit() routines). private class DefaultState extends State { @@ -392,41 +425,66 @@ public class NetworkMonitor extends StateMachine { switch (message.arg1) { case APP_RETURN_DISMISSED: - sendMessage(CMD_FORCE_REEVALUATION, 0 /* no UID */, 0); + sendMessage(CMD_FORCE_REEVALUATION, NO_UID, 0); break; case APP_RETURN_WANTED_AS_IS: mDontDisplaySigninNotification = true; // TODO: Distinguish this from a network that actually validates. - // Displaying the "!" on the system UI icon may still be a good idea. - transitionTo(mValidatedState); + // Displaying the "x" on the system UI icon may still be a good idea. + transitionTo(mEvaluatingPrivateDnsState); break; case APP_RETURN_UNWANTED: mDontDisplaySigninNotification = true; mUserDoesNotWant = true; - mConnectivityServiceHandler.sendMessage(obtainMessage( - EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, - mNetId, null)); + notifyNetworkTestResultInvalid(null); // TODO: Should teardown network. mUidResponsibleForReeval = 0; transitionTo(mEvaluatingState); break; } return HANDLED; - case CMD_PRIVATE_DNS_SETTINGS_CHANGED: - if (isValidationRequired()) { - // This performs a blocking DNS resolution of the - // strict mode hostname, if required. - resolvePrivateDnsConfig((DnsManager.PrivateDnsConfig) message.obj); - if ((mPrivateDnsCfg != null) && mPrivateDnsCfg.inStrictMode()) { - mConnectivityServiceHandler.sendMessage(obtainMessage( - EVENT_PRIVATE_DNS_CONFIG_RESOLVED, 0, mNetId, - new DnsManager.PrivateDnsConfig(mPrivateDnsCfg))); - } + case CMD_PRIVATE_DNS_SETTINGS_CHANGED: { + final PrivateDnsConfig cfg = (PrivateDnsConfig) message.obj; + if (!isValidationRequired() || cfg == null || !cfg.inStrictMode()) { + // No DNS resolution required. + // + // We don't force any validation in opportunistic mode + // here. Opportunistic mode nameservers are validated + // separately within netd. + // + // Reset Private DNS settings state. + mPrivateDnsProviderHostname = ""; + break; } - return HANDLED; + + mPrivateDnsProviderHostname = cfg.hostname; + + // DNS resolutions via Private DNS strict mode block for a + // few seconds (~4.2) checking for any IP addresses to + // arrive and validate. Initiating a (re)evaluation now + // should not significantly alter the validation outcome. + // + // No matter what: enqueue a validation request; one of + // three things can happen with this request: + // [1] ignored (EvaluatingState or CaptivePortalState) + // [2] transition to EvaluatingPrivateDnsState + // (DefaultState and ValidatedState) + // [3] handled (EvaluatingPrivateDnsState) + // + // The Private DNS configuration to be evaluated will: + // [1] be skipped (not in strict mode), or + // [2] validate (huzzah), or + // [3] encounter some problem (invalid hostname, + // no resolved IP addresses, IPs unreachable, + // port 853 unreachable, port 853 is not running a + // DNS-over-TLS server, et cetera). + sendMessage(CMD_EVALUATE_PRIVATE_DNS); + break; + } default: - return HANDLED; + break; } + return HANDLED; } } @@ -440,7 +498,7 @@ public class NetworkMonitor extends StateMachine { maybeLogEvaluationResult( networkEventType(validationStage(), EvaluationResult.VALIDATED)); mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, - NETWORK_TEST_RESULT_VALID, mNetId, mPrivateDnsCfg)); + NETWORK_TEST_RESULT_VALID, mNetId, null)); mValidations++; } @@ -449,10 +507,14 @@ public class NetworkMonitor extends StateMachine { switch (message.what) { case CMD_NETWORK_CONNECTED: transitionTo(mValidatedState); - return HANDLED; + break; + case CMD_EVALUATE_PRIVATE_DNS: + transitionTo(mEvaluatingPrivateDnsState); + break; default: return NOT_HANDLED; } + return HANDLED; } } @@ -569,11 +631,11 @@ public class NetworkMonitor extends StateMachine { case CMD_REEVALUATE: if (message.arg1 != mReevaluateToken || mUserDoesNotWant) return HANDLED; - // Don't bother validating networks that don't satisify the default request. + // Don't bother validating networks that don't satisfy the default request. // This includes: // - VPNs which can be considered explicitly desired by the user and the // user's desire trumps whether the network validates. - // - Networks that don't provide internet access. It's unclear how to + // - Networks that don't provide Internet access. It's unclear how to // validate such networks. // - Untrusted networks. It's unsafe to prompt the user to sign-in to // such networks and the user didn't express interest in connecting to @@ -588,7 +650,6 @@ public class NetworkMonitor extends StateMachine { // expensive metered network, or unwanted leaking of the User Agent string. if (!isValidationRequired()) { validationLog("Network would not satisfy default request, not validating"); - mPrivateDnsCfg = null; transitionTo(mValidatedState); return HANDLED; } @@ -601,20 +662,18 @@ public class NetworkMonitor extends StateMachine { // if this is found to cause problems. CaptivePortalProbeResult probeResult = isCaptivePortal(); if (probeResult.isSuccessful()) { - resolvePrivateDnsConfig(); - transitionTo(mValidatedState); + // Transit EvaluatingPrivateDnsState to get to Validated + // state (even if no Private DNS validation required). + transitionTo(mEvaluatingPrivateDnsState); } else if (probeResult.isPortal()) { - mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, - NETWORK_TEST_RESULT_INVALID, mNetId, probeResult.redirectUrl)); + notifyNetworkTestResultInvalid(probeResult.redirectUrl); mLastPortalProbeResult = probeResult; transitionTo(mCaptivePortalState); } else { final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0); sendMessageDelayed(msg, mReevaluateDelayMs); logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED); - mConnectivityServiceHandler.sendMessage(obtainMessage( - EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetId, - probeResult.redirectUrl)); + notifyNetworkTestResultInvalid(probeResult.redirectUrl); if (mAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) { // Don't continue to blame UID forever. TrafficStats.clearThreadStatsUid(); @@ -700,6 +759,110 @@ public class NetworkMonitor extends StateMachine { } } + private class EvaluatingPrivateDnsState extends State { + private int mPrivateDnsReevalDelayMs; + private PrivateDnsConfig mPrivateDnsConfig; + + @Override + public void enter() { + mPrivateDnsReevalDelayMs = INITIAL_REEVALUATE_DELAY_MS; + mPrivateDnsConfig = null; + sendMessage(CMD_EVALUATE_PRIVATE_DNS); + } + + @Override + public boolean processMessage(Message msg) { + switch (msg.what) { + case CMD_EVALUATE_PRIVATE_DNS: + if (inStrictMode()) { + if (!isStrictModeHostnameResolved()) { + resolveStrictModeHostname(); + + if (isStrictModeHostnameResolved()) { + notifyPrivateDnsConfigResolved(); + } else { + handlePrivateDnsEvaluationFailure(); + break; + } + } + + // Look up a one-time hostname, to bypass caching. + // + // Note that this will race with ConnectivityService + // code programming the DNS-over-TLS server IP addresses + // into netd (if invoked, above). If netd doesn't know + // the IP addresses yet, or if the connections to the IP + // addresses haven't yet been validated, netd will block + // for up to a few seconds before failing the lookup. + if (!sendPrivateDnsProbe()) { + handlePrivateDnsEvaluationFailure(); + break; + } + } + + // All good! + transitionTo(mValidatedState); + break; + default: + return NOT_HANDLED; + } + return HANDLED; + } + + private boolean inStrictMode() { + return !TextUtils.isEmpty(mPrivateDnsProviderHostname); + } + + private boolean isStrictModeHostnameResolved() { + return (mPrivateDnsConfig != null) && + mPrivateDnsConfig.hostname.equals(mPrivateDnsProviderHostname) && + (mPrivateDnsConfig.ips.length > 0); + } + + private void resolveStrictModeHostname() { + try { + // Do a blocking DNS resolution using the network-assigned nameservers. + mPrivateDnsConfig = new PrivateDnsConfig( + mPrivateDnsProviderHostname, + mNetwork.getAllByName(mPrivateDnsProviderHostname)); + } catch (UnknownHostException uhe) { + mPrivateDnsConfig = null; + } + } + + private void notifyPrivateDnsConfigResolved() { + mConnectivityServiceHandler.sendMessage(obtainMessage( + EVENT_PRIVATE_DNS_CONFIG_RESOLVED, 0, mNetId, mPrivateDnsConfig)); + } + + private void handlePrivateDnsEvaluationFailure() { + notifyNetworkTestResultInvalid(null); + + // Queue up a re-evaluation with backoff. + // + // TODO: Consider abandoning this state after a few attempts and + // transitioning back to EvaluatingState, to perhaps give ourselves + // the opportunity to (re)detect a captive portal or something. + sendMessageDelayed(CMD_EVALUATE_PRIVATE_DNS, mPrivateDnsReevalDelayMs); + mPrivateDnsReevalDelayMs *= 2; + if (mPrivateDnsReevalDelayMs > MAX_REEVALUATE_DELAY_MS) { + mPrivateDnsReevalDelayMs = MAX_REEVALUATE_DELAY_MS; + } + } + + private boolean sendPrivateDnsProbe() { + // q.v. system/netd/server/dns/DnsTlsTransport.cpp + final String ONE_TIME_HOSTNAME_SUFFIX = "-dnsotls-ds.metric.gstatic.com"; + final String host = UUID.randomUUID().toString().substring(0, 8) + + ONE_TIME_HOSTNAME_SUFFIX; + try { + final InetAddress[] ips = mNetworkAgentInfo.network().getAllByName(host); + return (ips != null && ips.length > 0); + } catch (UnknownHostException uhe) {} + return false; + } + } + // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at // most one per address family. This ensures we only wait up to 20 seconds for TCP connections // to complete, regardless of how many IP addresses a host has. @@ -710,7 +873,9 @@ public class NetworkMonitor extends StateMachine { @Override public InetAddress[] getAllByName(String host) throws UnknownHostException { - List<InetAddress> addrs = Arrays.asList(super.getAllByName(host)); + // Always bypass Private DNS. + final List<InetAddress> addrs = Arrays.asList( + ResolvUtil.blockingResolveAllLocally(this, host)); // Ensure the address family of the first address is tried first. LinkedHashMap<Class, InetAddress> addressByFamily = new LinkedHashMap<>(); @@ -1065,44 +1230,6 @@ public class NetworkMonitor extends StateMachine { return null; } - public void notifyPrivateDnsSettingsChanged(DnsManager.PrivateDnsConfig newCfg) { - // Cancel any outstanding resolutions. - removeMessages(CMD_PRIVATE_DNS_SETTINGS_CHANGED); - // Send the update to the proper thread. - sendMessage(CMD_PRIVATE_DNS_SETTINGS_CHANGED, newCfg); - } - - private void resolvePrivateDnsConfig() { - resolvePrivateDnsConfig(DnsManager.getPrivateDnsConfig(mContext.getContentResolver())); - } - - private void resolvePrivateDnsConfig(DnsManager.PrivateDnsConfig cfg) { - // Nothing to do. - if (cfg == null) { - mPrivateDnsCfg = null; - return; - } - - // No DNS resolution required. - if (!cfg.inStrictMode()) { - mPrivateDnsCfg = cfg; - return; - } - - if ((mPrivateDnsCfg != null) && mPrivateDnsCfg.inStrictMode() && - (mPrivateDnsCfg.ips.length > 0) && mPrivateDnsCfg.hostname.equals(cfg.hostname)) { - // We have already resolved this strict mode hostname. Assume that - // Private DNS services won't be changing serving IP addresses very - // frequently and save ourselves one re-resolve. - return; - } - - mPrivateDnsCfg = cfg; - final DnsManager.PrivateDnsConfig resolvedCfg = DnsManager.tryBlockingResolveOf( - mNetwork, mPrivateDnsCfg.hostname); - if (resolvedCfg != null) mPrivateDnsCfg = resolvedCfg; - } - /** * @param responseReceived - whether or not we received a valid HTTP response to our request. * If false, isCaptivePortal and responseTimestampMs are ignored diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 5e1afeb571de..bfd34ac9ae05 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -169,16 +169,6 @@ class AutomaticBrightnessController { // Use -1 if there is no current auto-brightness value available. private int mScreenAutoBrightness = -1; - // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter) - private float mScreenAutoBrightnessAdjustment = 0.0f; - - // The maximum range of gamma adjustment possible using the screen - // auto-brightness adjustment setting. - private float mScreenAutoBrightnessAdjustmentMaxGamma; - - // The last screen auto-brightness gamma. (For printing in dump() only.) - private float mLastScreenAutoBrightnessGamma = 1.0f; - // The current display policy. This is useful, for example, for knowing when we're dozing, // where the light sensor may not be available. private int mDisplayPolicy = DisplayPowerRequest.POLICY_OFF; @@ -186,10 +176,8 @@ class AutomaticBrightnessController { // True if we are collecting a brightness adjustment sample, along with some data // for the initial state of the sample. private boolean mBrightnessAdjustmentSamplePending; - private float mBrightnessAdjustmentSampleOldAdjustment; private float mBrightnessAdjustmentSampleOldLux; private int mBrightnessAdjustmentSampleOldBrightness; - private float mBrightnessAdjustmentSampleOldGamma; // When the short term model is invalidated, we don't necessarily reset it (i.e. clear the // user's adjustment) immediately, but wait for a drastic enough change in the ambient light. @@ -200,12 +188,11 @@ class AutomaticBrightnessController { private float SHORT_TERM_MODEL_THRESHOLD_RATIO = 0.6f; public AutomaticBrightnessController(Callbacks callbacks, Looper looper, - SensorManager sensorManager, BrightnessMappingStrategy mapper, int lightSensorWarmUpTime, - int brightnessMin, int brightnessMax, float dozeScaleFactor, + SensorManager sensorManager, BrightnessMappingStrategy mapper, + int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, - int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma, - HysteresisLevels dynamicHysteresis) { + int ambientLightHorizon, HysteresisLevels dynamicHysteresis) { mCallbacks = callbacks; mSensorManager = sensorManager; mBrightnessMapper = mapper; @@ -221,7 +208,6 @@ class AutomaticBrightnessController { mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig; mAmbientLightHorizon = ambientLightHorizon; mWeightingIntercept = ambientLightHorizon; - mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma; mDynamicHysteresis = dynamicHysteresis; mShortTermModelValid = true; mShortTermModelAnchor = -1; @@ -243,7 +229,7 @@ class AutomaticBrightnessController { } public float getAutomaticScreenBrightnessAdjustment() { - return mScreenAutoBrightnessAdjustment; + return mBrightnessMapper.getAutoBrightnessAdjustment(); } public void configure(boolean enable, @Nullable BrightnessConfiguration configuration, @@ -257,7 +243,9 @@ class AutomaticBrightnessController { boolean dozing = (displayPolicy == DisplayPowerRequest.POLICY_DOZE); boolean changed = setBrightnessConfiguration(configuration); changed |= setDisplayPolicy(displayPolicy); - changed |= setScreenAutoBrightnessAdjustment(adjustment); + if (userChangedAutoBrightnessAdjustment) { + changed |= setAutoBrightnessAdjustment(adjustment); + } if (userChangedBrightness && enable) { // Update the brightness curve with the new user control point. It's critical this // happens after we update the autobrightness adjustment since it may reset it. @@ -322,9 +310,6 @@ class AutomaticBrightnessController { if (DEBUG) { Slog.d(TAG, "ShortTermModel: anchor=" + mShortTermModelAnchor); } - // Reset the brightness adjustment so that the next time we're queried for brightness we - // return the value the user set. - mScreenAutoBrightnessAdjustment = 0.0f; return true; } @@ -369,10 +354,6 @@ class AutomaticBrightnessController { pw.println(" mRecentLightSamples=" + mRecentLightSamples); pw.println(" mAmbientLightRingBuffer=" + mAmbientLightRingBuffer); pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness); - pw.println(" mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment); - pw.println(" mScreenAutoBrightnessAdjustmentMaxGamma=" - + mScreenAutoBrightnessAdjustmentMaxGamma); - pw.println(" mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma); pw.println(" mDisplayPolicy=" + mDisplayPolicy); pw.println(" mShortTermModelAnchor=" + mShortTermModelAnchor); @@ -429,8 +410,8 @@ class AutomaticBrightnessController { if (lightSensorRate != mCurrentLightSensorRate) { if (DEBUG) { Slog.d(TAG, "adjustLightSensorRate: " + - "previousRate=" + mCurrentLightSensorRate + ", " + - "currentRate=" + lightSensorRate); + "previousRate=" + mCurrentLightSensorRate + ", " + + "currentRate=" + lightSensorRate); } mCurrentLightSensorRate = lightSensorRate; mSensorManager.unregisterListener(mLightSensorListener); @@ -439,12 +420,8 @@ class AutomaticBrightnessController { } } - private boolean setScreenAutoBrightnessAdjustment(float adjustment) { - if (adjustment != mScreenAutoBrightnessAdjustment) { - mScreenAutoBrightnessAdjustment = adjustment; - return true; - } - return false; + private boolean setAutoBrightnessAdjustment(float adjustment) { + return mBrightnessMapper.setAutoBrightnessAdjustment(adjustment); } private void setAmbientLux(float lux) { @@ -466,12 +443,14 @@ class AutomaticBrightnessController { final float maxAmbientLux = mShortTermModelAnchor + mShortTermModelAnchor * SHORT_TERM_MODEL_THRESHOLD_RATIO; if (minAmbientLux < mAmbientLux && mAmbientLux < maxAmbientLux) { - Slog.d(TAG, "ShortTermModel: re-validate user data, ambient lux is " + - minAmbientLux + " < " + mAmbientLux + " < " + maxAmbientLux); + if (DEBUG) { + Slog.d(TAG, "ShortTermModel: re-validate user data, ambient lux is " + + minAmbientLux + " < " + mAmbientLux + " < " + maxAmbientLux); + } mShortTermModelValid = true; } else { Slog.d(TAG, "ShortTermModel: reset data, ambient lux is " + mAmbientLux + - "(" + minAmbientLux + ", " + maxAmbientLux + ")"); + "(" + minAmbientLux + ", " + maxAmbientLux + ")"); resetShortTermModel(); } } @@ -498,9 +477,9 @@ class AutomaticBrightnessController { } } if (DEBUG) { - Slog.d(TAG, "calculateAmbientLux: selected endIndex=" + endIndex + ", point=(" - + mAmbientLightRingBuffer.getTime(endIndex) + ", " - + mAmbientLightRingBuffer.getLux(endIndex) + ")"); + Slog.d(TAG, "calculateAmbientLux: selected endIndex=" + endIndex + ", point=(" + + mAmbientLightRingBuffer.getTime(endIndex) + ", " + + mAmbientLightRingBuffer.getLux(endIndex) + ")"); } float sum = 0; float totalWeight = 0; @@ -517,8 +496,8 @@ class AutomaticBrightnessController { float lux = mAmbientLightRingBuffer.getLux(i); if (DEBUG) { Slog.d(TAG, "calculateAmbientLux: [" + startTime + ", " + endTime + "]: " + - "lux=" + lux + ", " + - "weight=" + weight); + "lux=" + lux + ", " + + "weight=" + weight); } totalWeight += weight; sum += lux * weight; @@ -526,8 +505,8 @@ class AutomaticBrightnessController { } if (DEBUG) { Slog.d(TAG, "calculateAmbientLux: " + - "totalWeight=" + totalWeight + ", " + - "newAmbientLux=" + (sum / totalWeight)); + "totalWeight=" + totalWeight + ", " + + "newAmbientLux=" + (sum / totalWeight)); } return sum / totalWeight; } @@ -581,8 +560,8 @@ class AutomaticBrightnessController { if (time < timeWhenSensorWarmedUp) { if (DEBUG) { Slog.d(TAG, "updateAmbientLux: Sensor not ready yet: " + - "time=" + time + ", " + - "timeWhenSensorWarmedUp=" + timeWhenSensorWarmedUp); + "time=" + time + ", " + + "timeWhenSensorWarmedUp=" + timeWhenSensorWarmedUp); } mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, timeWhenSensorWarmedUp); @@ -621,10 +600,10 @@ class AutomaticBrightnessController { setAmbientLux(fastAmbientLux); if (DEBUG) { Slog.d(TAG, "updateAmbientLux: " + - ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + - "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold + ", " + - "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + - "mAmbientLux=" + mAmbientLux); + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold + ", " + + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + + "mAmbientLux=" + mAmbientLux); } updateAutoBrightness(true); nextBrightenTransition = nextAmbientLightBrighteningTransition(time); @@ -641,7 +620,7 @@ class AutomaticBrightnessController { nextTransitionTime > time ? nextTransitionTime : time + mNormalLightSensorRate; if (DEBUG) { Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for " + - nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime)); + nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime)); } mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime); } @@ -652,40 +631,17 @@ class AutomaticBrightnessController { } float value = mBrightnessMapper.getBrightness(mAmbientLux); - float gamma = 1.0f; - - if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT - && mScreenAutoBrightnessAdjustment != 0.0f) { - final float adjGamma = MathUtils.pow(mScreenAutoBrightnessAdjustmentMaxGamma, - Math.min(1.0f, Math.max(-1.0f, -mScreenAutoBrightnessAdjustment))); - gamma *= adjGamma; - if (DEBUG) { - Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma); - } - } - - if (gamma != 1.0f) { - final float in = value; - value = MathUtils.pow(value, gamma); - if (DEBUG) { - Slog.d(TAG, "updateAutoBrightness: " + - "gamma=" + gamma + ", " + - "in=" + in + ", " + - "out=" + value); - } - } int newScreenAutoBrightness = clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); if (mScreenAutoBrightness != newScreenAutoBrightness) { if (DEBUG) { Slog.d(TAG, "updateAutoBrightness: " + - "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + - "newScreenAutoBrightness=" + newScreenAutoBrightness); + "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + + "newScreenAutoBrightness=" + newScreenAutoBrightness); } mScreenAutoBrightness = newScreenAutoBrightness; - mLastScreenAutoBrightnessGamma = gamma; if (sendUpdate) { mCallbacks.updateBrightness(); } @@ -700,10 +656,8 @@ class AutomaticBrightnessController { private void prepareBrightnessAdjustmentSample() { if (!mBrightnessAdjustmentSamplePending) { mBrightnessAdjustmentSamplePending = true; - mBrightnessAdjustmentSampleOldAdjustment = mScreenAutoBrightnessAdjustment; mBrightnessAdjustmentSampleOldLux = mAmbientLuxValid ? mAmbientLux : -1; mBrightnessAdjustmentSampleOldBrightness = mScreenAutoBrightness; - mBrightnessAdjustmentSampleOldGamma = mLastScreenAutoBrightnessGamma; } else { mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE); } @@ -725,22 +679,16 @@ class AutomaticBrightnessController { if (mAmbientLuxValid && mScreenAutoBrightness >= 0) { if (DEBUG) { Slog.d(TAG, "Auto-brightness adjustment changed by user: " + - "adj=" + mScreenAutoBrightnessAdjustment + ", " + - "lux=" + mAmbientLux + ", " + - "brightness=" + mScreenAutoBrightness + ", " + - "gamma=" + mLastScreenAutoBrightnessGamma + ", " + - "ring=" + mAmbientLightRingBuffer); + "lux=" + mAmbientLux + ", " + + "brightness=" + mScreenAutoBrightness + ", " + + "ring=" + mAmbientLightRingBuffer); } EventLog.writeEvent(EventLogTags.AUTO_BRIGHTNESS_ADJ, - mBrightnessAdjustmentSampleOldAdjustment, mBrightnessAdjustmentSampleOldLux, mBrightnessAdjustmentSampleOldBrightness, - mBrightnessAdjustmentSampleOldGamma, - mScreenAutoBrightnessAdjustment, mAmbientLux, - mScreenAutoBrightness, - mLastScreenAutoBrightnessGamma); + mScreenAutoBrightness); } } } diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index 4313d1724214..f74daf2be38b 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -28,6 +28,7 @@ import android.util.Spline; import com.android.internal.util.Preconditions; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.display.utils.Plog; import java.io.PrintWriter; import java.util.Arrays; @@ -46,6 +47,8 @@ public abstract class BrightnessMappingStrategy { private static final float LUX_GRAD_SMOOTHING = 0.25f; private static final float MAX_GRAD = 1.0f; + private static final Plog PLOG = Plog.createSystemPlog(TAG); + @Nullable public static BrightnessMappingStrategy create(Resources resources) { float[] luxLevels = getLuxLevels(resources.getIntArray( @@ -54,6 +57,9 @@ public abstract class BrightnessMappingStrategy { com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); float[] brightnessLevelsNits = getFloatArray(resources.obtainTypedArray( com.android.internal.R.array.config_autoBrightnessDisplayValuesNits)); + float autoBrightnessAdjustmentMaxGamma = resources.getFraction( + com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma, + 1, 1); float[] nitsRange = getFloatArray(resources.obtainTypedArray( com.android.internal.R.array.config_screenBrightnessNits)); @@ -68,14 +74,16 @@ public abstract class BrightnessMappingStrategy { com.android.internal.R.integer.config_screenBrightnessSettingMaximum); if (backlightRange[0] > minimumBacklight || backlightRange[backlightRange.length - 1] < maximumBacklight) { - Slog.w(TAG, "Screen brightness mapping does not cover whole range of available" - + " backlight values, autobrightness functionality may be impaired."); + Slog.w(TAG, "Screen brightness mapping does not cover whole range of available " + + "backlight values, autobrightness functionality may be impaired."); } BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(); builder.setCurve(luxLevels, brightnessLevelsNits); - return new PhysicalMappingStrategy(builder.build(), nitsRange, backlightRange); + return new PhysicalMappingStrategy(builder.build(), nitsRange, backlightRange, + autoBrightnessAdjustmentMaxGamma); } else if (isValidMapping(luxLevels, brightnessLevelsBacklight)) { - return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight); + return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight, + autoBrightnessAdjustmentMaxGamma); } else { return null; } @@ -173,6 +181,26 @@ public abstract class BrightnessMappingStrategy { public abstract float getBrightness(float lux); /** + * Returns the current auto-brightness adjustment. + * + * The returned adjustment is a value in the range [-1.0, 1.0] such that + * {@code config_autoBrightnessAdjustmentMaxGamma<sup>-adjustment</sup>} is used to gamma + * correct the brightness curve. + */ + public abstract float getAutoBrightnessAdjustment(); + + /** + * Sets the auto-brightness adjustment. + * + * @param adjustment The desired auto-brightness adjustment. + * @return Whether the auto-brightness adjustment has changed. + * + * @Deprecated The auto-brightness adjustment should not be set directly, but rather inferred + * from user data points. + */ + public abstract boolean setAutoBrightnessAdjustment(float adjustment); + + /** * Converts the provided backlight value to nits if possible. * * Returns -1.0f if there's no available mapping for the backlight to nits. @@ -200,12 +228,13 @@ public abstract class BrightnessMappingStrategy { */ public abstract void clearUserDataPoints(); - /** @return true if there are any short term adjustments applied to the curve */ + /** @return True if there are any short term adjustments applied to the curve. */ public abstract boolean hasUserDataPoints(); - /** @return true if the current brightness config is the default one */ + /** @return True if the current brightness configuration is the default one. */ public abstract boolean isDefaultConfig(); + /** @return The default brightness configuration. */ public abstract BrightnessConfiguration getDefaultConfig(); public abstract void dump(PrintWriter pw); @@ -216,22 +245,8 @@ public abstract class BrightnessMappingStrategy { return (float) brightness / PowerManager.BRIGHTNESS_ON; } - private static Spline createSpline(float[] x, float[] y) { - Spline spline = Spline.createSpline(x, y); - if (DEBUG) { - Slog.d(TAG, "Spline: " + spline); - for (float v = 1f; v < x[x.length - 1] * 1.25f; v *= 1.25f) { - Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v))); - } - } - return spline; - } - private static Pair<float[], float[]> insertControlPoint( float[] luxLevels, float[] brightnessLevels, float lux, float brightness) { - if (DEBUG) { - Slog.d(TAG, "Inserting new control point at (" + lux + ", " + brightness + ")"); - } final int idx = findInsertionPoint(luxLevels, lux); final float[] newLuxLevels; final float[] newBrightnessLevels; @@ -274,9 +289,7 @@ public abstract class BrightnessMappingStrategy { private static void smoothCurve(float[] lux, float[] brightness, int idx) { if (DEBUG) { - Slog.d(TAG, "smoothCurve(lux=" + Arrays.toString(lux) - + ", brightness=" + Arrays.toString(brightness) - + ", idx=" + idx + ")"); + PLOG.logCurve("unsmoothed curve", lux, brightness); } float prevLux = lux[idx]; float prevBrightness = brightness[idx]; @@ -294,7 +307,6 @@ public abstract class BrightnessMappingStrategy { prevBrightness = newBrightness; brightness[i] = newBrightness; } - // Smooth curve for data points below the newly introduced point prevLux = lux[idx]; prevBrightness = brightness[idx]; @@ -312,8 +324,7 @@ public abstract class BrightnessMappingStrategy { brightness[i] = newBrightness; } if (DEBUG) { - Slog.d(TAG, "Smoothed Curve: lux=" + Arrays.toString(lux) - + ", brightness=" + Arrays.toString(brightness)); + PLOG.logCurve("smoothed curve", lux, brightness); } } @@ -323,6 +334,72 @@ public abstract class BrightnessMappingStrategy { - MathUtils.log(prevLux + LUX_GRAD_SMOOTHING))); } + private static float inferAutoBrightnessAdjustment(float maxGamma, + float desiredBrightness, float currentBrightness) { + float adjustment = 0; + float gamma = Float.NaN; + // Extreme edge cases: use a simpler heuristic, as proper gamma correction around the edges + // affects the curve rather drastically. + if (currentBrightness <= 0.1f || currentBrightness >= 0.9f) { + adjustment = (desiredBrightness - currentBrightness) * 2; + // Edge case: darkest adjustment possible. + } else if (desiredBrightness == 0) { + adjustment = -1; + // Edge case: brightest adjustment possible. + } else if (desiredBrightness == 1) { + adjustment = +1; + } else { + // current^gamma = desired => gamma = log[current](desired) + gamma = MathUtils.log(desiredBrightness) / MathUtils.log(currentBrightness); + // max^-adjustment = gamma => adjustment = -log[max](gamma) + adjustment = -MathUtils.constrain( + MathUtils.log(gamma) / MathUtils.log(maxGamma), -1, 1); + } + if (DEBUG) { + Slog.d(TAG, "inferAutoBrightnessAdjustment: " + maxGamma + "^" + -adjustment + "=" + + MathUtils.pow(maxGamma, -adjustment) + " == " + gamma); + Slog.d(TAG, "inferAutoBrightnessAdjustment: " + currentBrightness + "^" + gamma + "=" + + MathUtils.pow(currentBrightness, gamma) + " == " + desiredBrightness); + } + return adjustment; + } + + private static Pair<float[], float[]> getAdjustedCurve(float[] lux, float[] brightness, + float userLux, float userBrightness, float adjustment, float maxGamma) { + float[] newLux = lux; + float[] newBrightness = Arrays.copyOf(brightness, brightness.length); + if (DEBUG) { + PLOG.logCurve("unadjusted curve", newLux, newBrightness); + } + adjustment = MathUtils.constrain(adjustment, -1, 1); + float gamma = MathUtils.pow(maxGamma, -adjustment); + if (DEBUG) { + Slog.d(TAG, "getAdjustedCurve: " + maxGamma + "^" + -adjustment + "=" + + MathUtils.pow(maxGamma, -adjustment) + " == " + gamma); + } + if (gamma != 1) { + for (int i = 0; i < newBrightness.length; i++) { + newBrightness[i] = MathUtils.pow(newBrightness[i], gamma); + } + } + if (DEBUG) { + PLOG.logCurve("gamma adjusted curve", newLux, newBrightness); + } + if (userLux != -1) { + Pair<float[], float[]> curve = insertControlPoint(newLux, newBrightness, userLux, + userBrightness); + newLux = curve.first; + newBrightness = curve.second; + if (DEBUG) { + PLOG.logCurve("gamma and user adjusted curve", newLux, newBrightness); + // This is done for comparison. + curve = insertControlPoint(lux, brightness, userLux, userBrightness); + PLOG.logCurve("user adjusted curve", curve.first ,curve.second); + } + } + return Pair.create(newLux, newBrightness); + } + /** * A {@link BrightnessMappingStrategy} that maps from ambient room brightness directly to the * backlight of the display. @@ -337,10 +414,12 @@ public abstract class BrightnessMappingStrategy { private final float[] mBrightness; private Spline mSpline; + private float mMaxGamma; + private float mAutoBrightnessAdjustment; private float mUserLux; private float mUserBrightness; - public SimpleMappingStrategy(float[] lux, int[] brightness) { + public SimpleMappingStrategy(float[] lux, int[] brightness, float maxGamma) { Preconditions.checkArgument(lux.length != 0 && brightness.length != 0, "Lux and brightness arrays must not be empty!"); Preconditions.checkArgument(lux.length == brightness.length, @@ -357,9 +436,14 @@ public abstract class BrightnessMappingStrategy { mBrightness[i] = normalizeAbsoluteBrightness(brightness[i]); } - mSpline = createSpline(mLux, mBrightness); + mMaxGamma = maxGamma; + mAutoBrightnessAdjustment = 0; mUserLux = -1; mUserBrightness = -1; + if (DEBUG) { + PLOG.start("simple mapping strategy"); + } + computeSpline(); } @Override @@ -373,27 +457,65 @@ public abstract class BrightnessMappingStrategy { } @Override + public float getAutoBrightnessAdjustment() { + return mAutoBrightnessAdjustment; + } + + @Override + public boolean setAutoBrightnessAdjustment(float adjustment) { + adjustment = MathUtils.constrain(adjustment, -1, 1); + if (adjustment == mAutoBrightnessAdjustment) { + return false; + } + if (DEBUG) { + Slog.d(TAG, "setAutoBrightnessAdjustment: " + mAutoBrightnessAdjustment + " => " + + adjustment); + PLOG.start("auto-brightness adjustment"); + } + mAutoBrightnessAdjustment = adjustment; + computeSpline(); + return true; + } + + @Override public float convertToNits(int backlight) { return -1.0f; } @Override public void addUserDataPoint(float lux, float brightness) { + float unadjustedBrightness = getUnadjustedBrightness(lux); if (DEBUG){ - Slog.d(TAG, "addUserDataPoint(lux=" + lux + ", brightness=" + brightness + ")"); + Slog.d(TAG, "addUserDataPoint: (" + lux + "," + brightness + ")"); + PLOG.start("add user data point") + .logPoint("user data point", lux, brightness) + .logPoint("current brightness", lux, unadjustedBrightness); + } + float adjustment = inferAutoBrightnessAdjustment(mMaxGamma, + brightness /* desiredBrightness */, + unadjustedBrightness /* currentBrightness */); + if (DEBUG) { + Slog.d(TAG, "addUserDataPoint: " + mAutoBrightnessAdjustment + " => " + + adjustment); } - Pair<float[], float[]> curve = insertControlPoint(mLux, mBrightness, lux, brightness); - mSpline = createSpline(curve.first, curve.second); + mAutoBrightnessAdjustment = adjustment; mUserLux = lux; mUserBrightness = brightness; + computeSpline(); } @Override public void clearUserDataPoints() { if (mUserLux != -1) { - mSpline = createSpline(mLux, mBrightness); + if (DEBUG) { + Slog.d(TAG, "clearUserDataPoints: " + mAutoBrightnessAdjustment + " => 0"); + PLOG.start("clear user data points") + .logPoint("user data point", mUserLux, mUserBrightness); + } + mAutoBrightnessAdjustment = 0; mUserLux = -1; mUserBrightness = -1; + computeSpline(); } } @@ -408,15 +530,30 @@ public abstract class BrightnessMappingStrategy { } @Override - public BrightnessConfiguration getDefaultConfig() { return null; } + public BrightnessConfiguration getDefaultConfig() { + return null; + } @Override public void dump(PrintWriter pw) { pw.println("SimpleMappingStrategy"); pw.println(" mSpline=" + mSpline); + pw.println(" mMaxGamma=" + mMaxGamma); + pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); pw.println(" mUserLux=" + mUserLux); pw.println(" mUserBrightness=" + mUserBrightness); } + + private void computeSpline() { + Pair<float[], float[]> curve = getAdjustedCurve(mLux, mBrightness, mUserLux, + mUserBrightness, mAutoBrightnessAdjustment, mMaxGamma); + mSpline = Spline.createSpline(curve.first, curve.second); + } + + private float getUnadjustedBrightness(float lux) { + Spline spline = Spline.createSpline(mLux, mBrightness); + return spline.interpolate(lux); + } } /** A {@link BrightnessMappingStrategy} that maps from ambient room brightness to the physical @@ -445,11 +582,13 @@ public abstract class BrightnessMappingStrategy { // a brightness in nits. private Spline mBacklightToNitsSpline; + private float mMaxGamma; + private float mAutoBrightnessAdjustment; private float mUserLux; private float mUserBrightness; - public PhysicalMappingStrategy(BrightnessConfiguration config, - float[] nits, int[] backlight) { + public PhysicalMappingStrategy(BrightnessConfiguration config, float[] nits, + int[] backlight, float maxGamma) { Preconditions.checkArgument(nits.length != 0 && backlight.length != 0, "Nits and backlight arrays must not be empty!"); Preconditions.checkArgument(nits.length == backlight.length, @@ -459,6 +598,8 @@ public abstract class BrightnessMappingStrategy { Preconditions.checkArrayElementsInRange(backlight, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON, "backlight"); + mMaxGamma = maxGamma; + mAutoBrightnessAdjustment = 0; mUserLux = -1; mUserBrightness = -1; @@ -469,11 +610,15 @@ public abstract class BrightnessMappingStrategy { normalizedBacklight[i] = normalizeAbsoluteBrightness(backlight[i]); } - mNitsToBacklightSpline = createSpline(nits, normalizedBacklight); - mBacklightToNitsSpline = createSpline(normalizedBacklight, nits); + mNitsToBacklightSpline = Spline.createSpline(nits, normalizedBacklight); + mBacklightToNitsSpline = Spline.createSpline(normalizedBacklight, nits); mDefaultConfig = config; - setBrightnessConfiguration(config); + if (DEBUG) { + PLOG.start("physical mapping strategy"); + } + mConfig = config; + computeSpline(); } @Override @@ -484,10 +629,11 @@ public abstract class BrightnessMappingStrategy { if (config.equals(mConfig)) { return false; } - - Pair<float[], float[]> curve = config.getCurve(); - mBrightnessSpline = createSpline(curve.first /*lux*/, curve.second /*nits*/); + if (DEBUG) { + PLOG.start("brightness configuration"); + } mConfig = config; + computeSpline(); return true; } @@ -499,31 +645,65 @@ public abstract class BrightnessMappingStrategy { } @Override + public float getAutoBrightnessAdjustment() { + return mAutoBrightnessAdjustment; + } + + @Override + public boolean setAutoBrightnessAdjustment(float adjustment) { + adjustment = MathUtils.constrain(adjustment, -1, 1); + if (adjustment == mAutoBrightnessAdjustment) { + return false; + } + if (DEBUG) { + Slog.d(TAG, "setAutoBrightnessAdjustment: " + mAutoBrightnessAdjustment + " => " + + adjustment); + PLOG.start("auto-brightness adjustment"); + } + mAutoBrightnessAdjustment = adjustment; + computeSpline(); + return true; + } + + @Override public float convertToNits(int backlight) { return mBacklightToNitsSpline.interpolate(normalizeAbsoluteBrightness(backlight)); } @Override - public void addUserDataPoint(float lux, float backlight) { + public void addUserDataPoint(float lux, float brightness) { + float unadjustedBrightness = getUnadjustedBrightness(lux); if (DEBUG){ - Slog.d(TAG, "addUserDataPoint(lux=" + lux + ", backlight=" + backlight + ")"); + Slog.d(TAG, "addUserDataPoint: (" + lux + "," + brightness + ")"); + PLOG.start("add user data point") + .logPoint("user data point", lux, brightness) + .logPoint("current brightness", lux, unadjustedBrightness); } - float brightness = mBacklightToNitsSpline.interpolate(backlight); - Pair<float[], float[]> defaultCurve = mConfig.getCurve(); - Pair<float[], float[]> newCurve = - insertControlPoint(defaultCurve.first, defaultCurve.second, lux, brightness); - mBrightnessSpline = createSpline(newCurve.first, newCurve.second); + float adjustment = inferAutoBrightnessAdjustment(mMaxGamma, + brightness /* desiredBrightness */, + unadjustedBrightness /* currentBrightness */); + if (DEBUG) { + Slog.d(TAG, "addUserDataPoint: " + mAutoBrightnessAdjustment + " => " + + adjustment); + } + mAutoBrightnessAdjustment = adjustment; mUserLux = lux; mUserBrightness = brightness; + computeSpline(); } @Override public void clearUserDataPoints() { if (mUserLux != -1) { - Pair<float[], float[]> defaultCurve = mConfig.getCurve(); - mBrightnessSpline = createSpline(defaultCurve.first, defaultCurve.second); + if (DEBUG) { + Slog.d(TAG, "clearUserDataPoints: " + mAutoBrightnessAdjustment + " => 0"); + PLOG.start("clear user data points") + .logPoint("user data point", mUserLux, mUserBrightness); + } + mAutoBrightnessAdjustment = 0; mUserLux = -1; mUserBrightness = -1; + computeSpline(); } } @@ -538,7 +718,9 @@ public abstract class BrightnessMappingStrategy { } @Override - public BrightnessConfiguration getDefaultConfig() { return mDefaultConfig; } + public BrightnessConfiguration getDefaultConfig() { + return mDefaultConfig; + } @Override public void dump(PrintWriter pw) { @@ -546,8 +728,35 @@ public abstract class BrightnessMappingStrategy { pw.println(" mConfig=" + mConfig); pw.println(" mBrightnessSpline=" + mBrightnessSpline); pw.println(" mNitsToBacklightSpline=" + mNitsToBacklightSpline); + pw.println(" mMaxGamma=" + mMaxGamma); + pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); pw.println(" mUserLux=" + mUserLux); pw.println(" mUserBrightness=" + mUserBrightness); } + + private void computeSpline() { + Pair<float[], float[]> defaultCurve = mConfig.getCurve(); + float[] defaultLux = defaultCurve.first; + float[] defaultNits = defaultCurve.second; + float[] defaultBacklight = new float[defaultNits.length]; + for (int i = 0; i < defaultBacklight.length; i++) { + defaultBacklight[i] = mNitsToBacklightSpline.interpolate(defaultNits[i]); + } + Pair<float[], float[]> curve = getAdjustedCurve(defaultLux, defaultBacklight, mUserLux, + mUserBrightness, mAutoBrightnessAdjustment, mMaxGamma); + float[] lux = curve.first; + float[] backlight = curve.second; + float[] nits = new float[backlight.length]; + for (int i = 0; i < nits.length; i++) { + nits[i] = mBacklightToNitsSpline.interpolate(backlight[i]); + } + mBrightnessSpline = Spline.createSpline(lux, nits); + } + + private float getUnadjustedBrightness(float lux) { + Pair<float[], float[]> curve = mConfig.getCurve(); + Spline spline = Spline.createSpline(curve.first, curve.second); + return mNitsToBacklightSpline.interpolate(spline.interpolate(lux)); + } } } diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java index b3d309dda25b..37035c3a343c 100644 --- a/services/core/java/com/android/server/display/ColorDisplayService.java +++ b/services/core/java/com/android/server/display/ColorDisplayService.java @@ -300,6 +300,11 @@ public final class ColorDisplayService extends SystemService dtm.setColorMode(mode, mIsActivated ? mMatrixNight : MATRIX_IDENTITY); } + @Override + public void onAccessibilityTransformChanged(boolean state) { + onDisplayColorModeChanged(mController.getColorMode()); + } + /** * Set coefficients based on native mode. Use DisplayTransformManager#isNativeModeEnabled while * setting is stable; when setting is changing, pass native mode selection directly. diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 1784ef14ecc1..5f4c8efd4d9e 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -424,9 +424,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp); int ambientLightHorizon = resources.getInteger( com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon); - float autoBrightnessAdjustmentMaxGamma = resources.getFraction( - com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma, - 1, 1); int lightSensorWarmUpTimeConfig = resources.getInteger( com.android.internal.R.integer.config_lightSensorWarmupTime); @@ -450,7 +447,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon, - autoBrightnessAdjustmentMaxGamma, dynamicHysteresis); + dynamicHysteresis); } else { mUseSoftwareAutoBrightnessConfig = false; } diff --git a/services/core/java/com/android/server/display/utils/Plog.java b/services/core/java/com/android/server/display/utils/Plog.java new file mode 100644 index 000000000000..3a18387c2482 --- /dev/null +++ b/services/core/java/com/android/server/display/utils/Plog.java @@ -0,0 +1,141 @@ +/* + * 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.server.display.utils; + + +import java.lang.StringBuilder; +import java.lang.System; + +import android.util.Slog; + +/** + * A utility to log multiple points and curves in a structured way so they can be easily consumed + * by external tooling + * + * To start a plot, call {@link Plog.start} with the plot's title; to add a point to it, call + * {@link Plog.logPoint} with the point name (that will appear in the legend) and coordinates; and + * to log a curve, call {@link Plog.logCurve} with its name and points. + */ +public abstract class Plog { + // A unique identifier used to group points and curves that belong on the same plot. + private long mId; + + /** + * Returns a Plog instance that emits messages to the system log. + * + * @param tag The tag of the emitted messages in the system log. + * @return A plog instance that emits messages to the system log. + */ + public static Plog createSystemPlog(String tag) { + return new SystemPlog(tag); + } + + /** + * Start a new plot. + * + * @param title The plot title. + * @return The Plog instance (for chaining). + */ + public Plog start(String title) { + mId = System.currentTimeMillis(); + write(formatTitle(title)); + return this; + } + + /** + * Adds a point to the current plot. + * + * @param name The point name (that will appear in the legend). + * @param x The point x coordinate. + * @param y The point y coordinate. + * @return The Plog instance (for chaining). + */ + public Plog logPoint(String name, float x, float y) { + write(formatPoint(name, x, y)); + return this; + } + + /** + * Adds a curve to the current plot. + * + * @param name The curve name (that will appear in the legend). + * @param xs The curve x coordinates. + * @param ys The curve y coordinates. + * @return The Plog instance (for chaining). + */ + public Plog logCurve(String name, float[] xs, float[] ys) { + write(formatCurve(name, xs, ys)); + return this; + } + + private String formatTitle(String title) { + return "title: " + title; + } + + private String formatPoint(String name, float x, float y) { + return "point: " + name + ": (" + x + "," + y + ")"; + } + + private String formatCurve(String name, float[] xs, float[] ys) { + StringBuilder sb = new StringBuilder(); + sb.append("curve: " + name + ": ["); + int n = xs.length <= ys.length ? xs.length : ys.length; + for (int i = 0; i < n; i++) { + sb.append("(" + xs[i] + "," + ys[i] + "),"); + } + sb.append("]"); + return sb.toString(); + } + + private void write(String message) { + emit("[PLOG " + mId + "] " + message); + } + + /** + * Emits a message (depending on the concrete Plog implementation). + * + * @param message The message. + */ + protected abstract void emit(String message); + + /** + * A Plog that emits messages to the system log. + */ + public static class SystemPlog extends Plog { + // The tag of the emitted messages in the system log. + private final String mTag; + + /** + * Returns a Plog instance that emits messages to the system log. + * + * @param tag The tag of the emitted messages in the system log. + * @return A Plog instance that emits messages to the system log. + */ + public SystemPlog(String tag) { + mTag = tag; + } + + /** + * Emits a message to the system log. + * + * @param message The message. + */ + protected void emit(String message) { + Slog.d(mTag, message); + } + } +} diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index 66817fad4e5b..736aa46352bd 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -127,7 +127,7 @@ import java.util.function.Predicate; * Any function with the suffix 'Locked' also needs to lock on {@link #mJobs}. * @hide */ -public final class JobSchedulerService extends com.android.server.SystemService +public class JobSchedulerService extends com.android.server.SystemService implements StateChangedListener, JobCompletedListener { public static final String TAG = "JobScheduler"; public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -781,6 +781,10 @@ public final class JobSchedulerService extends com.android.server.SystemService } }; + public Context getTestableContext() { + return getContext(); + } + public Object getLock() { return mLock; } diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java index 8365fd2e5427..0c66c5b22d76 100644 --- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java +++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java @@ -30,12 +30,12 @@ import android.net.NetworkInfo; import android.net.NetworkPolicyManager; import android.net.NetworkRequest; import android.net.TrafficStats; -import android.os.Process; import android.os.UserHandle; import android.text.format.DateUtils; import android.util.ArraySet; import android.util.Log; import android.util.Slog; +import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; @@ -46,6 +46,7 @@ import com.android.server.job.JobSchedulerService.Constants; import com.android.server.job.JobServiceContext; import com.android.server.job.StateControllerProto; +import java.util.Objects; import java.util.function.Predicate; /** @@ -63,7 +64,6 @@ public final class ConnectivityController extends StateController implements private final ConnectivityManager mConnManager; private final NetworkPolicyManager mNetPolicyManager; - private boolean mConnected; @GuardedBy("mLock") private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>(); @@ -74,9 +74,11 @@ public final class ConnectivityController extends StateController implements mConnManager = mContext.getSystemService(ConnectivityManager.class); mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); - mConnected = false; + // We're interested in all network changes; internally we match these + // network changes against the active network for each UID with jobs. + final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); + mConnManager.registerNetworkCallback(request, mNetworkCallback); - mConnManager.registerDefaultNetworkCallback(mNetworkCallback); mNetPolicyManager.registerListener(mNetPolicyListener); } @@ -198,14 +200,18 @@ public final class ConnectivityController extends StateController implements } private boolean updateConstraintsSatisfied(JobStatus jobStatus) { + final Network network = mConnManager.getActiveNetworkForUid(jobStatus.getSourceUid()); + final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network); + return updateConstraintsSatisfied(jobStatus, network, capabilities); + } + + private boolean updateConstraintsSatisfied(JobStatus jobStatus, Network network, + NetworkCapabilities capabilities) { // TODO: consider matching against non-active networks - final int jobUid = jobStatus.getSourceUid(); final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0; - - final Network network = mConnManager.getActiveNetworkForUid(jobUid, ignoreBlocked); - final NetworkInfo info = mConnManager.getNetworkInfoForUid(network, jobUid, ignoreBlocked); - final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network); + final NetworkInfo info = mConnManager.getNetworkInfoForUid(network, + jobStatus.getSourceUid(), ignoreBlocked); final boolean connected = (info != null) && info.isConnected(); final boolean satisfied = isSatisfied(jobStatus, network, capabilities, mConstants); @@ -218,12 +224,6 @@ public final class ConnectivityController extends StateController implements // using non-default routes. jobStatus.network = network; - // Track system-uid connected/validated as a general reportable proxy for the - // overall state of connectivity constraint satisfiability. - if (jobUid == Process.SYSTEM_UID) { - mConnected = connected; - } - if (DEBUG) { Slog.i(TAG, "Connectivity " + (changed ? "CHANGED" : "unchanged") + " for " + jobStatus + ": connected=" + connected @@ -233,18 +233,48 @@ public final class ConnectivityController extends StateController implements } /** - * Update all jobs tracked by this controller. + * Update any jobs tracked by this controller that match given filters. * - * @param uid only update jobs belonging to this UID, or {@code -1} to + * @param filterUid only update jobs belonging to this UID, or {@code -1} to * update all tracked jobs. + * @param filterNetwork only update jobs that would use this + * {@link Network}, or {@code null} to update all tracked jobs. */ - private void updateTrackedJobs(int uid) { + private void updateTrackedJobs(int filterUid, Network filterNetwork) { synchronized (mLock) { + // Since this is a really hot codepath, temporarily cache any + // answers that we get from ConnectivityManager. + final SparseArray<Network> uidToNetwork = new SparseArray<>(); + final SparseArray<NetworkCapabilities> networkToCapabilities = new SparseArray<>(); + boolean changed = false; - for (int i = mTrackedJobs.size()-1; i >= 0; i--) { + for (int i = mTrackedJobs.size() - 1; i >= 0; i--) { final JobStatus js = mTrackedJobs.valueAt(i); - if (uid == -1 || uid == js.getSourceUid()) { - changed |= updateConstraintsSatisfied(js); + final int uid = js.getSourceUid(); + + final boolean uidMatch = (filterUid == -1 || filterUid == uid); + if (uidMatch) { + Network network = uidToNetwork.get(uid); + if (network == null) { + network = mConnManager.getActiveNetworkForUid(uid); + uidToNetwork.put(uid, network); + } + + // Update either when we have a network match, or when the + // job hasn't yet been evaluated against the currently + // active network; typically when we just lost a network. + final boolean networkMatch = (filterNetwork == null + || Objects.equals(filterNetwork, network)); + final boolean forceUpdate = !Objects.equals(js.network, network); + if (networkMatch || forceUpdate) { + final int netId = network != null ? network.netId : -1; + NetworkCapabilities capabilities = networkToCapabilities.get(netId); + if (capabilities == null) { + capabilities = mConnManager.getNetworkCapabilities(network); + networkToCapabilities.put(netId, capabilities); + } + changed |= updateConstraintsSatisfied(js, network, capabilities); + } } } if (changed) { @@ -273,19 +303,19 @@ public final class ConnectivityController extends StateController implements private final NetworkCallback mNetworkCallback = new NetworkCallback() { @Override - public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { + public void onCapabilitiesChanged(Network network, NetworkCapabilities capabilities) { if (DEBUG) { - Slog.v(TAG, "onCapabilitiesChanged() : " + networkCapabilities); + Slog.v(TAG, "onCapabilitiesChanged: " + network); } - updateTrackedJobs(-1); + updateTrackedJobs(-1, network); } @Override public void onLost(Network network) { if (DEBUG) { - Slog.v(TAG, "Network lost"); + Slog.v(TAG, "onLost: " + network); } - updateTrackedJobs(-1); + updateTrackedJobs(-1, network); } }; @@ -293,25 +323,9 @@ public final class ConnectivityController extends StateController implements @Override public void onUidRulesChanged(int uid, int uidRules) { if (DEBUG) { - Slog.v(TAG, "Uid rules changed for " + uid); + Slog.v(TAG, "onUidRulesChanged: " + uid); } - updateTrackedJobs(uid); - } - - @Override - public void onRestrictBackgroundChanged(boolean restrictBackground) { - if (DEBUG) { - Slog.v(TAG, "Background restriction change to " + restrictBackground); - } - updateTrackedJobs(-1); - } - - @Override - public void onUidPoliciesChanged(int uid, int uidPolicies) { - if (DEBUG) { - Slog.v(TAG, "Uid policy changed for " + uid); - } - updateTrackedJobs(uid); + updateTrackedJobs(uid, null); } }; @@ -319,9 +333,6 @@ public final class ConnectivityController extends StateController implements @Override public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) { - pw.println("System connected: " + mConnected); - pw.println(); - for (int i = 0; i < mTrackedJobs.size(); i++) { final JobStatus js = mTrackedJobs.valueAt(i); if (predicate.test(js)) { @@ -343,8 +354,6 @@ public final class ConnectivityController extends StateController implements final long token = proto.start(fieldId); final long mToken = proto.start(StateControllerProto.CONNECTIVITY); - proto.write(StateControllerProto.ConnectivityController.IS_CONNECTED, mConnected); - for (int i = 0; i < mTrackedJobs.size(); i++) { final JobStatus js = mTrackedJobs.valueAt(i); if (!predicate.test(js)) { diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java index 495109d88fd7..c2be28336406 100644 --- a/services/core/java/com/android/server/job/controllers/StateController.java +++ b/services/core/java/com/android/server/job/controllers/StateController.java @@ -41,7 +41,7 @@ public abstract class StateController { StateController(JobSchedulerService service) { mService = service; mStateChangedListener = service; - mContext = service.getContext(); + mContext = service.getTestableContext(); mLock = service.getLock(); mConstants = service.getConstants(); } diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java index 6cf8f86aed83..639cc70fa275 100644 --- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java +++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java @@ -18,6 +18,7 @@ package com.android.server.notification; import android.annotation.Nullable; import android.app.Notification; +import android.app.Person; import android.content.Context; import android.content.pm.PackageManager; import android.database.ContentObserver; @@ -332,8 +333,8 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor { return array; } - if (arrayList.get(0) instanceof Notification.Person) { - ArrayList<Notification.Person> list = (ArrayList<Notification.Person>) arrayList; + if (arrayList.get(0) instanceof Person) { + ArrayList<Person> list = (ArrayList<Person>) arrayList; final int N = list.size(); String[] array = new String[N]; for (int i = 0; i < N; i++) { diff --git a/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java b/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java index 416469bd3be1..9c00d1abafea 100644 --- a/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java +++ b/services/core/java/com/android/server/wm/AnimatingAppWindowTokenRegistry.java @@ -37,6 +37,8 @@ class AnimatingAppWindowTokenRegistry { private ArrayList<Runnable> mTmpRunnableList = new ArrayList<>(); + private boolean mEndingDeferredFinish; + /** * Notifies that an {@link AppWindowToken} has started animating. */ @@ -50,6 +52,11 @@ class AnimatingAppWindowTokenRegistry { void notifyFinished(AppWindowToken token) { mAnimatingTokens.remove(token); mFinishedTokens.remove(token); + + // If we were the last token, make sure the end all deferred finishes. + if (mAnimatingTokens.isEmpty()) { + endDeferringFinished(); + } } /** @@ -78,16 +85,28 @@ class AnimatingAppWindowTokenRegistry { } private void endDeferringFinished() { - // Copy it into a separate temp list to avoid modifying the collection while iterating as - // calling the callback may call back into notifyFinished. - for (int i = mFinishedTokens.size() - 1; i >= 0; i--) { - mTmpRunnableList.add(mFinishedTokens.valueAt(i)); + + // Don't start recursing. Running the finished listener invokes notifyFinished, which may + // invoked us again. + if (mEndingDeferredFinish) { + return; } - mFinishedTokens.clear(); - for (int i = mTmpRunnableList.size() - 1; i >= 0; i--) { - mTmpRunnableList.get(i).run(); + try { + mEndingDeferredFinish = true; + + // Copy it into a separate temp list to avoid modifying the collection while iterating + // as calling the callback may call back into notifyFinished. + for (int i = mFinishedTokens.size() - 1; i >= 0; i--) { + mTmpRunnableList.add(mFinishedTokens.valueAt(i)); + } + mFinishedTokens.clear(); + for (int i = mTmpRunnableList.size() - 1; i >= 0; i--) { + mTmpRunnableList.get(i).run(); + } + mTmpRunnableList.clear(); + } finally { + mEndingDeferredFinish = false; } - mTmpRunnableList.clear(); } void dump(PrintWriter pw, String header, String prefix) { diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 8fa94fb4de6b..9a4db655a0fa 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1714,7 +1714,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree adapter = new LocalAnimationAdapter( new WindowAnimationSpec(a, mTmpPoint, mTmpRect, mService.mAppTransition.canSkipFirstFrame(), - mService.mAppTransition.getAppStackClipMode()), + mService.mAppTransition.getAppStackClipMode(), + true /* isAppAnimation */), mService.mSurfaceAnimationRunner); if (a.getZAdjustment() == Animation.ZORDER_TOP) { mNeedsZBoost = true; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 0771b53325c0..79eb2c9ebe17 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3728,8 +3728,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED; - if (policy.isKeyguardShowingAndNotOccluded() - || mService.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) { + // Only allow force setting the orientation when all unknown visibilities have been + // resolved, as otherwise we just may be starting another occluding activity. + final boolean isUnoccluding = + mService.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE + && mService.mUnknownAppVisibilityController.allResolved(); + if (policy.isKeyguardShowingAndNotOccluded() || isUnoccluding) { return mLastKeyguardForcedOrientation; } diff --git a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java index 529aacc0f91d..d89d6f056218 100644 --- a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java +++ b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java @@ -146,6 +146,13 @@ class LocalAnimationAdapter implements AnimationAdapter { return false; } + /** + * @return {@code true} if we need to wake-up SurfaceFlinger earlier during this animation. + * + * @see Transaction#setEarlyWakeup + */ + default boolean needsEarlyWakeup() { return false; } + void dump(PrintWriter pw, String prefix); default void writeToProto(ProtoOutputStream proto, long fieldId) { diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index c4f51976fb1b..e8f4545e1c27 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -18,8 +18,10 @@ package com.android.server.wm; import static android.app.ActivityManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; @@ -68,14 +70,14 @@ public class RecentsAnimationController implements DeathRecipient { private static final boolean DEBUG = false; private static final long FAILSAFE_DELAY = 1000; - public static final int REORDER_KEEP_HOME_IN_PLACE = 0; - public static final int REORDER_MOVE_HOME_TO_TOP = 1; - public static final int REORDER_MOVE_HOME_TO_ORIGINAL_POSITION = 2; + public static final int REORDER_KEEP_IN_PLACE = 0; + public static final int REORDER_MOVE_TO_TOP = 1; + public static final int REORDER_MOVE_TO_ORIGINAL_POSITION = 2; @IntDef(prefix = { "REORDER_MODE_" }, value = { - REORDER_KEEP_HOME_IN_PLACE, - REORDER_MOVE_HOME_TO_TOP, - REORDER_MOVE_HOME_TO_ORIGINAL_POSITION + REORDER_KEEP_IN_PLACE, + REORDER_MOVE_TO_TOP, + REORDER_MOVE_TO_ORIGINAL_POSITION }) public @interface ReorderMode {} @@ -85,11 +87,11 @@ public class RecentsAnimationController implements DeathRecipient { private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>(); private final int mDisplayId; private final Runnable mFailsafeRunnable = () -> { - cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); + cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); }; // The recents component app token that is shown behind the visibile tasks - private AppWindowToken mHomeAppToken; + private AppWindowToken mTargetAppToken; private Rect mMinimizedHomeBounds = new Rect(); // We start the RecentsAnimationController in a pending-start state since we need to wait for @@ -160,8 +162,8 @@ public class RecentsAnimationController implements DeathRecipient { // Note, the callback will handle its own synchronization, do not lock on WM lock // prior to calling the callback mCallbacks.onAnimationFinished(moveHomeToTop - ? REORDER_MOVE_HOME_TO_TOP - : REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); + ? REORDER_MOVE_TO_TOP + : REORDER_MOVE_TO_ORIGINAL_POSITION); } finally { Binder.restoreCallingIdentity(token); } @@ -240,7 +242,7 @@ public class RecentsAnimationController implements DeathRecipient { * because it may call cancelAnimation() which needs to properly clean up the controller * in the window manager. */ - public void initialize(SparseBooleanArray recentTaskIds) { + public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) { // Make leashes for each of the visible tasks and add it to the recents animation to be // started final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId); @@ -251,7 +253,7 @@ public class RecentsAnimationController implements DeathRecipient { final WindowConfiguration config = task.getWindowConfiguration(); if (config.tasksAreFloating() || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY - || config.getActivityType() == ACTIVITY_TYPE_HOME) { + || config.getActivityType() == targetActivityType) { continue; } addAnimation(task, !recentTaskIds.get(task.mTaskId)); @@ -259,23 +261,23 @@ public class RecentsAnimationController implements DeathRecipient { // Skip the animation if there is nothing to animate if (mPendingAnimations.isEmpty()) { - cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); + cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); return; } try { mRunner.asBinder().linkToDeath(this, 0); } catch (RemoteException e) { - cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); + cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); return; } - // Adjust the wallpaper visibility for the showing home activity - final AppWindowToken recentsComponentAppToken = - dc.getHomeStack().getTopChild().getTopFullscreenAppToken(); + // Adjust the wallpaper visibility for the showing target activity + final AppWindowToken recentsComponentAppToken = dc.getStack(WINDOWING_MODE_UNDEFINED, + targetActivityType).getTopChild().getTopFullscreenAppToken(); if (recentsComponentAppToken != null) { if (DEBUG) Log.d(TAG, "setHomeApp(" + recentsComponentAppToken.getName() + ")"); - mHomeAppToken = recentsComponentAppToken; + mTargetAppToken = recentsComponentAppToken; if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) { dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; dc.setLayoutNeeded(); @@ -319,12 +321,14 @@ public class RecentsAnimationController implements DeathRecipient { new RemoteAnimationTarget[appAnimations.size()]); mPendingStart = false; - final Rect minimizedHomeBounds = - mHomeAppToken != null && mHomeAppToken.inSplitScreenSecondaryWindowingMode() - ? mMinimizedHomeBounds : null; - final Rect contentInsets = - mHomeAppToken != null && mHomeAppToken.findMainWindow() != null - ? mHomeAppToken.findMainWindow().mContentInsets : null; + final Rect minimizedHomeBounds = mTargetAppToken != null + && mTargetAppToken.inSplitScreenSecondaryWindowingMode() + ? mMinimizedHomeBounds + : null; + final Rect contentInsets = mTargetAppToken != null + && mTargetAppToken.findMainWindow() != null + ? mTargetAppToken.findMainWindow().mContentInsets + : null; mRunner.onAnimationStart_New(mController, appTargets, contentInsets, minimizedHomeBounds); } catch (RemoteException e) { @@ -363,8 +367,7 @@ public class RecentsAnimationController implements DeathRecipient { for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { final TaskAnimationAdapter adapter = mPendingAnimations.get(i); adapter.mTask.setCanAffectSystemUiFlags(true); - if (reorderMode == REORDER_MOVE_HOME_TO_TOP - || reorderMode == REORDER_KEEP_HOME_IN_PLACE) { + if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) { adapter.mTask.dontAnimateDimExit(); } adapter.mCapturedFinishCallback.onAnimationFinished(adapter); @@ -383,12 +386,12 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void binderDied() { - cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); + cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); } void checkAnimationReady(WallpaperController wallpaperController) { if (mPendingStart) { - final boolean wallpaperReady = !isHomeAppOverWallpaper() + final boolean wallpaperReady = !isTargetOverWallpaper() || (wallpaperController.getWallpaperTarget() != null && wallpaperController.wallpaperTransitionReady()); if (wallpaperReady) { @@ -402,8 +405,8 @@ public class RecentsAnimationController implements DeathRecipient { } boolean isWallpaperVisible(WindowState w) { - return w != null && w.mAppToken != null && mHomeAppToken == w.mAppToken - && isHomeAppOverWallpaper(); + return w != null && w.mAppToken != null && mTargetAppToken == w.mAppToken + && isTargetOverWallpaper(); } boolean hasInputConsumerForApp(AppWindowToken appToken) { @@ -412,12 +415,12 @@ public class RecentsAnimationController implements DeathRecipient { boolean updateInputConsumerForApp(InputConsumerImpl recentsAnimationInputConsumer, boolean hasFocus) { - // Update the input consumer touchable region to match the home app main window - final WindowState homeAppMainWindow = mHomeAppToken != null - ? mHomeAppToken.findMainWindow() + // Update the input consumer touchable region to match the target app main window + final WindowState targetAppMainWindow = mTargetAppToken != null + ? mTargetAppToken.findMainWindow() : null; - if (homeAppMainWindow != null) { - homeAppMainWindow.getBounds(mTmpRect); + if (targetAppMainWindow != null) { + targetAppMainWindow.getBounds(mTmpRect); recentsAnimationInputConsumer.mWindowHandle.hasFocus = hasFocus; recentsAnimationInputConsumer.mWindowHandle.touchableRegion.set(mTmpRect); return true; @@ -425,11 +428,11 @@ public class RecentsAnimationController implements DeathRecipient { return false; } - private boolean isHomeAppOverWallpaper() { - if (mHomeAppToken == null) { + private boolean isTargetOverWallpaper() { + if (mTargetAppToken == null) { return false; } - return mHomeAppToken.windowsCanBeWallpaperTarget(); + return mTargetAppToken.windowsCanBeWallpaperTarget(); } boolean isAnimatingTask(Task task) { @@ -511,7 +514,7 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void onAnimationCancelled(SurfaceControl animationLeash) { - cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); + cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); } @Override @@ -549,6 +552,6 @@ public class RecentsAnimationController implements DeathRecipient { final String innerPrefix = prefix + " "; pw.print(prefix); pw.println(RecentsAnimationController.class.getSimpleName() + ":"); pw.print(innerPrefix); pw.println("mPendingStart=" + mPendingStart); - pw.print(innerPrefix); pw.println("mHomeAppToken=" + mHomeAppToken); + pw.print(innerPrefix); pw.println("mTargetAppToken=" + mTargetAppToken); } } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 98fcb0be935c..7211533c1b44 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -220,6 +220,9 @@ class SurfaceAnimationRunner { } private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) { + if (a.mAnimSpec.needsEarlyWakeup()) { + t.setEarlyWakeup(); + } a.mAnimSpec.apply(t, a.mLeash, currentPlayTime); } diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index a9e53a14a210..597b39eaf826 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -173,6 +173,8 @@ class TaskSnapshotSurface implements StartingSurface { windowFlags = topFullscreenWindow.getAttrs().flags; windowPrivateFlags = topFullscreenWindow.getAttrs().privateFlags; + layoutParams.packageName = mainWindow.getAttrs().packageName; + layoutParams.windowAnimations = mainWindow.getAttrs().windowAnimations; layoutParams.dimAmount = mainWindow.getAttrs().dimAmount; layoutParams.type = TYPE_APPLICATION_STARTING; layoutParams.format = snapshot.getSnapshot().getFormat(); diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 6de157929243..7eaca5d42bb1 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -26,7 +26,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; -import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION; +import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER; @@ -620,7 +620,7 @@ class WallpaperController { // If there was a recents animation in progress, cancel that animation if (mService.getRecentsAnimationController() != null) { mService.getRecentsAnimationController().cancelAnimation( - REORDER_MOVE_HOME_TO_ORIGINAL_POSITION); + REORDER_MOVE_TO_ORIGINAL_POSITION); } return true; } diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java index 7b7cb30ac64d..548e23a4d984 100644 --- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java +++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java @@ -47,21 +47,24 @@ public class WindowAnimationSpec implements AnimationSpec { private final Point mPosition = new Point(); private final ThreadLocal<TmpValues> mThreadLocalTmps = ThreadLocal.withInitial(TmpValues::new); private final boolean mCanSkipFirstFrame; + private final boolean mIsAppAnimation; private final Rect mStackBounds = new Rect(); private int mStackClipMode; private final Rect mTmpRect = new Rect(); public WindowAnimationSpec(Animation animation, Point position, boolean canSkipFirstFrame) { - this(animation, position, null /* stackBounds */, canSkipFirstFrame, STACK_CLIP_NONE); + this(animation, position, null /* stackBounds */, canSkipFirstFrame, STACK_CLIP_NONE, + false /* isAppAnimation */); } public WindowAnimationSpec(Animation animation, Point position, Rect stackBounds, - boolean canSkipFirstFrame, int stackClipMode) { + boolean canSkipFirstFrame, int stackClipMode, boolean isAppAnimation) { mAnimation = animation; if (position != null) { mPosition.set(position.x, position.y); } mCanSkipFirstFrame = canSkipFirstFrame; + mIsAppAnimation = isAppAnimation; mStackClipMode = stackClipMode; if (stackBounds != null) { mStackBounds.set(stackBounds); @@ -135,6 +138,11 @@ public class WindowAnimationSpec implements AnimationSpec { } @Override + public boolean needsEarlyWakeup() { + return mIsAppAnimation; + } + + @Override public void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.println(mAnimation); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0c9504f775d0..fa7eff261409 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2689,7 +2689,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void initializeRecentsAnimation( + public void initializeRecentsAnimation(int targetActivityType, IRecentsAnimationRunner recentsAnimationRunner, RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId, SparseBooleanArray recentTaskIds) { @@ -2697,7 +2697,7 @@ public class WindowManagerService extends IWindowManager.Stub mRecentsAnimationController = new RecentsAnimationController(this, recentsAnimationRunner, callbacks, displayId); mAppTransition.updateBooster(); - mRecentsAnimationController.initialize(recentTaskIds); + mRecentsAnimationController.initialize(targetActivityType, recentTaskIds); } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 84df128b3841..c5269e172f2a 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2001,6 +2001,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // Try starting an animation. if (mWinAnimator.applyAnimationLocked(transit, false)) { mAnimatingExit = true; + + // mAnimatingExit affects canAffectSystemUiFlags(). Run layout such that + // any change from that is performed immediately. + setDisplayLayoutNeeded(); + mService.requestTraversal(); } //TODO (multidisplay): Magnification is supported only for the default display. if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 6f50ee27d134..5519d229faea 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -725,7 +725,6 @@ public final class SystemServer { NetworkStatsService networkStats = null; NetworkPolicyManagerService networkPolicy = null; ConnectivityService connectivity = null; - NetworkScoreService networkScore = null; NsdService serviceDiscovery= null; WindowManagerService wm = null; SerialService serial = null; @@ -1090,12 +1089,7 @@ public final class SystemServer { } traceBeginAndSlog("StartNetworkScoreService"); - try { - networkScore = new NetworkScoreService(context); - ServiceManager.addService(Context.NETWORK_SCORE_SERVICE, networkScore); - } catch (Throwable e) { - reportWtf("starting Network Score Service", e); - } + mSystemServiceManager.startService(NetworkScoreService.Lifecycle.class); traceEnd(); traceBeginAndSlog("StartNetworkStatsService"); @@ -1728,7 +1722,6 @@ public final class SystemServer { final NetworkStatsService networkStatsF = networkStats; final NetworkPolicyManagerService networkPolicyF = networkPolicy; final ConnectivityService connectivityF = connectivity; - final NetworkScoreService networkScoreF = networkScore; final LocationManagerService locationF = location; final CountryDetectorService countryDetectorF = countryDetector; final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater; @@ -1789,13 +1782,6 @@ public final class SystemServer { reportWtf("starting System UI", e); } traceEnd(); - traceBeginAndSlog("MakeNetworkScoreReady"); - try { - if (networkScoreF != null) networkScoreF.systemReady(); - } catch (Throwable e) { - reportWtf("making Network Score Service ready", e); - } - traceEnd(); traceBeginAndSlog("MakeNetworkManagementServiceReady"); try { if (networkManagementF != null) networkManagementF.systemReady(); @@ -1917,13 +1903,6 @@ public final class SystemServer { } traceEnd(); - traceBeginAndSlog("MakeNetworkScoreServiceReady"); - try { - if (networkScoreF != null) networkScoreF.systemRunning(); - } catch (Throwable e) { - reportWtf("Notifying NetworkScoreService running", e); - } - traceEnd(); traceBeginAndSlog("IncidentDaemonReady"); try { // TODO: Switch from checkService to getService once it's always diff --git a/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java index 46b364c21559..43701e900ab1 100644 --- a/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java @@ -25,6 +25,7 @@ import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Secure; +import android.provider.Settings.System; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.test.mock.MockContentResolver; @@ -895,6 +896,52 @@ public class ColorDisplayServiceTest { assertActivated(true /* activated */); } + @Test + public void accessibility_colorInversion_transformActivated() { + setAccessibilityColorInversion(true); + setColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + + startService(); + assertAccessibilityTransformActivated(true /* activated */ ); + assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED); + } + + @Test + public void accessibility_colorCorrection_transformActivated() { + setAccessibilityColorCorrection(true); + setColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + + startService(); + assertAccessibilityTransformActivated(true /* activated */ ); + assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED); + } + + @Test + public void accessibility_all_transformActivated() { + setAccessibilityColorCorrection(true); + setAccessibilityColorInversion(true); + setColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + + startService(); + assertAccessibilityTransformActivated(true /* activated */ ); + assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED); + } + + @Test + public void accessibility_none_transformActivated() { + setAccessibilityColorCorrection(false); + setAccessibilityColorInversion(false); + setColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + + startService(); + assertAccessibilityTransformActivated(false /* activated */ ); + assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + assertActiveColorMode(ColorDisplayController.COLOR_MODE_NATURAL); + } + /** * Configures Night display to use a custom schedule. * @@ -935,6 +982,35 @@ public class ColorDisplayServiceTest { } /** + * Configures the Accessibility color correction setting state. + * + * @param state {@code true} if color inversion should be activated + */ + private void setAccessibilityColorCorrection(boolean state) { + Secure.putIntForUser(mContext.getContentResolver(), + Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, state ? 1 : 0, mUserId); + } + + /** + * Configures the Accessibility color inversion setting state. + * + * @param state {@code true} if color inversion should be activated + */ + private void setAccessibilityColorInversion(boolean state) { + Secure.putIntForUser(mContext.getContentResolver(), + Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, state ? 1 : 0, mUserId); + } + + /** + * Configures color mode via ColorDisplayController. + * + * @param mode the color mode to set + */ + private void setColorMode(int mode) { + mColorDisplayController.setColorMode(mode); + } + + /** * Convenience method to start {@link #mColorDisplayService}. */ private void startService() { @@ -962,6 +1038,41 @@ public class ColorDisplayServiceTest { } /** + * Convenience method for asserting that Accessibility color transform is detected. + * + * @param state {@code true} if any Accessibility transform should be activated + */ + private void assertAccessibilityTransformActivated(boolean state) { + assertWithMessage("Unexpected Accessibility color transform state") + .that(mColorDisplayController.getAccessibilityTransformActivated()) + .isEqualTo(state); + } + + /** + * Convenience method for asserting that the active color mode matches expectation. + * + * @param mode the expected active color mode. + */ + private void assertActiveColorMode(int mode) { + assertWithMessage("Unexpected color mode setting") + .that(mColorDisplayController.getColorMode()) + .isEqualTo(mode); + } + + /** + * Convenience method for asserting that the user chosen color mode matches expectation. + * + * @param mode the expected color mode setting. + */ + private void assertUserColorMode(int mode) { + final int actualMode = System.getIntForUser(mContext.getContentResolver(), + System.DISPLAY_COLOR_MODE, -1, mUserId); + assertWithMessage("Unexpected color mode setting") + .that(actualMode) + .isEqualTo(mode); + } + + /** * Convenience for making a {@link LocalTime} instance with an offset relative to now. * * @param offsetMinutes the offset relative to now (in minutes) diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java index b9ddf5c88fd4..c78fcd3858fc 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java @@ -24,8 +24,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 com.android.server.am.ActivityStack.ActivityState.DESTROYED; -import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; import static com.android.server.am.ActivityStack.ActivityState.PAUSING; import static com.android.server.am.ActivityStack.ActivityState.RESUMED; import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING; @@ -43,9 +41,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import android.app.servertransaction.DestroyActivityItem; import android.content.pm.ActivityInfo; -import android.os.Debug; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; @@ -67,6 +63,7 @@ import org.junit.Test; public class ActivityStackTests extends ActivityTestsBase { private ActivityManagerService mService; private ActivityStackSupervisor mSupervisor; + private ActivityDisplay mDefaultDisplay; private ActivityStack mStack; private TaskRecord mTask; @@ -77,8 +74,9 @@ public class ActivityStackTests extends ActivityTestsBase { mService = createActivityManagerService(); mSupervisor = mService.mStackSupervisor; - mStack = mService.mStackSupervisor.getDefaultDisplay().createStack( - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); + mDefaultDisplay = mService.mStackSupervisor.getDefaultDisplay(); + mStack = mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); mTask = new TaskBuilder(mSupervisor).setStack(mStack).build(); } @@ -112,9 +110,8 @@ public class ActivityStackTests extends ActivityTestsBase { public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception { // Create primary splitscreen stack. This will create secondary stacks and places the // existing fullscreen stack on the bottom. - final ActivityStack primarySplitScreen = mService.mStackSupervisor.getDefaultDisplay() - .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, - true /* onTop */); + final ActivityStack primarySplitScreen = mDefaultDisplay.createStack( + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Assert windowing mode. assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); @@ -124,8 +121,7 @@ public class ActivityStackTests extends ActivityTestsBase { null /* task */); // Assert that stack is at the bottom. - assertEquals(mService.mStackSupervisor.getDefaultDisplay().getIndexOf(primarySplitScreen), - 0); + assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0); // Ensure no longer in splitscreen. assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN); @@ -165,16 +161,15 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldBeVisible_Fullscreen() throws Exception { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(display, + final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertTrue(homeStack.shouldBeVisible(null /* starting */)); assertTrue(pinnedStack.shouldBeVisible(null /* starting */)); - final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack // should be visible since it is always on-top. @@ -191,14 +186,13 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldBeVisible_SplitScreen() throws Exception { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); // Home stack should always be fullscreen for this test. homeStack.setSupportsSplitScreen(false); - final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display, + final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display, + final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); // Home stack shouldn't be visible if both halves of split-screen are opaque. @@ -214,7 +208,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); - final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(display, + final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); // First split-screen secondary shouldn't be visible behind another opaque split-split // secondary. @@ -228,7 +222,7 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */)); - final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack. @@ -258,11 +252,11 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldBeVisible_Finishing() throws Exception { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); + final TestActivityStack translucentStack = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); translucentStack.setIsTranslucent(true); assertTrue(homeStack.shouldBeVisible(null /* starting */)); @@ -286,76 +280,74 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - display.removeChild(mStack); + mDefaultDisplay.removeChild(mStack); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); homeStack.setIsTranslucent(false); fullscreenStack.setIsTranslucent(false); // Ensure that we don't move the home stack if it is already behind the top fullscreen stack - int homeStackIndex = display.getIndexOf(homeStack); - assertTrue(display.getStackAboveHome() == fullscreenStack); - display.moveHomeStackBehindBottomMostVisibleStack(); - assertTrue(display.getIndexOf(homeStack) == homeStackIndex); + int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack); + mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack); + assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex); } @Test public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - display.removeChild(mStack); + mDefaultDisplay.removeChild(mStack); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); homeStack.setIsTranslucent(false); fullscreenStack.setIsTranslucent(true); // Ensure that we don't move the home stack if it is already behind the top fullscreen stack - int homeStackIndex = display.getIndexOf(homeStack); - assertTrue(display.getStackAboveHome() == fullscreenStack); - display.moveHomeStackBehindBottomMostVisibleStack(); - assertTrue(display.getIndexOf(homeStack) == homeStackIndex); + int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack); + mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack); + assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex); } @Test public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - display.removeChild(mStack); + mDefaultDisplay.removeChild(mStack); - final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); homeStack.setIsTranslucent(false); fullscreenStack.setIsTranslucent(false); // Ensure we don't move the home stack if it is already on top - int homeStackIndex = display.getIndexOf(homeStack); - assertTrue(display.getStackAboveHome() == null); - display.moveHomeStackBehindBottomMostVisibleStack(); - assertTrue(display.getIndexOf(homeStack) == homeStackIndex); + int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == null); + mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack); + assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex); } @Test public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - display.removeChild(mStack); + mDefaultDisplay.removeChild(mStack); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); homeStack.setIsTranslucent(false); @@ -364,22 +356,23 @@ public class ActivityStackTests extends ActivityTestsBase { // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the // pinned stack - assertTrue(display.getStackAboveHome() == fullscreenStack1); - display.moveHomeStackBehindBottomMostVisibleStack(); - assertTrue(display.getStackAboveHome() == fullscreenStack2); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1); + mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2); } @Test public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - display.removeChild(mStack); + mDefaultDisplay.removeChild(mStack); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); + final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); homeStack.setIsTranslucent(false); fullscreenStack1.setIsTranslucent(false); @@ -387,21 +380,22 @@ public class ActivityStackTests extends ActivityTestsBase { // Ensure that we move the home stack behind the bottom most non-translucent fullscreen // stack - assertTrue(display.getStackAboveHome() == fullscreenStack1); - display.moveHomeStackBehindBottomMostVisibleStack(); - assertTrue(display.getStackAboveHome() == fullscreenStack1); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1); + mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1); } @Test public void testMoveHomeStackBehindStack_BehindHomeStack() { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - display.removeChild(mStack); - - final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + mDefaultDisplay.removeChild(mStack); + + final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); homeStack.setIsTranslucent(false); @@ -409,45 +403,49 @@ public class ActivityStackTests extends ActivityTestsBase { fullscreenStack2.setIsTranslucent(false); // Ensure we don't move the home stack behind itself - int homeStackIndex = display.getIndexOf(homeStack); - display.moveHomeStackBehindStack(homeStack); - assertTrue(display.getIndexOf(homeStack) == homeStackIndex); + int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack); + mDefaultDisplay.moveStackBehindStack(homeStack, homeStack); + assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex); } @Test public void testMoveHomeStackBehindStack() { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - display.removeChild(mStack); - - final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display, + mDefaultDisplay.removeChild(mStack); + + final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); - display.moveHomeStackBehindStack(fullscreenStack1); - assertTrue(display.getStackAboveHome() == fullscreenStack1); - display.moveHomeStackBehindStack(fullscreenStack2); - assertTrue(display.getStackAboveHome() == fullscreenStack2); - display.moveHomeStackBehindStack(fullscreenStack4); - assertTrue(display.getStackAboveHome() == fullscreenStack4); - display.moveHomeStackBehindStack(fullscreenStack2); - assertTrue(display.getStackAboveHome() == fullscreenStack2); + mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1); + mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2); + mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack4); + mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2); + assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2); } @Test public void testSplitScreenMoveToFront() throws Exception { - final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay(); - final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(display, - WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(display, + final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest( + mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); splitScreenPrimary.setIsTranslucent(false); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java index f740654e436b..e4e97012367a 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.app.admin.FreezeInterval; +import android.app.admin.FreezePeriod; import android.app.admin.SystemUpdatePolicy; import android.os.Parcel; import android.support.test.runner.AndroidJUnit4; @@ -42,15 +42,15 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.LocalTime; +import java.time.MonthDay; import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; + /** * Unit tests for {@link android.app.admin.SystemUpdatePolicy}. * Throughout this test, we use "MM-DD" format to denote dates without year. @@ -224,36 +224,36 @@ public final class SystemUpdatePolicyTest { @Test public void testDistanceWithoutLeapYear() { - assertEquals(364, FreezeInterval.distanceWithoutLeapYear( + assertEquals(364, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2016, 12, 31), LocalDate.of(2016, 1, 1))); - assertEquals(365, FreezeInterval.distanceWithoutLeapYear( + assertEquals(365, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2017, 1, 1), LocalDate.of(2016, 1, 1))); - assertEquals(365, FreezeInterval.distanceWithoutLeapYear( + assertEquals(365, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2017, 2, 28), LocalDate.of(2016, 2, 29))); - assertEquals(-365, FreezeInterval.distanceWithoutLeapYear( + assertEquals(-365, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2016, 1, 1), LocalDate.of(2017, 1, 1))); - assertEquals(1, FreezeInterval.distanceWithoutLeapYear( + assertEquals(1, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 29))); - assertEquals(1, FreezeInterval.distanceWithoutLeapYear( + assertEquals(1, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 28))); - assertEquals(0, FreezeInterval.distanceWithoutLeapYear( + assertEquals(0, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2016, 2, 29), LocalDate.of(2016, 2, 28))); - assertEquals(0, FreezeInterval.distanceWithoutLeapYear( + assertEquals(0, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2016, 2, 28), LocalDate.of(2016, 2, 28))); - assertEquals(59, FreezeInterval.distanceWithoutLeapYear( + assertEquals(59, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2016, 3, 1), LocalDate.of(2016, 1, 1))); - assertEquals(59, FreezeInterval.distanceWithoutLeapYear( + assertEquals(59, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2017, 3, 1), LocalDate.of(2017, 1, 1))); - assertEquals(365 * 40, FreezeInterval.distanceWithoutLeapYear( + assertEquals(365 * 40, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2040, 1, 1), LocalDate.of(2000, 1, 1))); - assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear( + assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2019, 3, 1), LocalDate.of(2017, 3, 1))); - assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear( + assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2018, 3, 1), LocalDate.of(2016, 3, 1))); - assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear( + assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear( LocalDate.of(2017, 3, 1), LocalDate.of(2015, 3, 1))); } @@ -386,10 +386,10 @@ public final class SystemUpdatePolicyTest { // Two freeze periods p = SystemUpdatePolicy.createAutomaticInstallPolicy(); - setFreezePeriods(p, "05-01", "06-01", "11-01", "01-29"); - // automatic policy for July, August, September and October + setFreezePeriods(p, "05-01", "06-01", "10-15", "01-10"); + // automatic policy for July, August, September and October until 15th assertInstallationOption( - SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(92), + SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(31 + 30 + 14), millis_2018_08_01, p); } @@ -435,18 +435,18 @@ public final class SystemUpdatePolicyTest { String... dates) throws Exception { SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy(); setFreezePeriods(p, dates); - p.validateAgainstPreviousFreezePeriod(parseDate(prevStart), parseDate(prevEnd), - parseDate(now)); + p.validateAgainstPreviousFreezePeriod(parseLocalDate(prevStart), + parseLocalDate(prevEnd), parseLocalDate(now)); } // "MM-DD" format for date private void setFreezePeriods(SystemUpdatePolicy policy, String... dates) throws Exception { - List<Pair<Integer, Integer>> periods = new ArrayList<>(); - LocalDate lastDate = null; + List<FreezePeriod> periods = new ArrayList<>(); + MonthDay lastDate = null; for (String date : dates) { - LocalDate currentDate = parseDate(date); + MonthDay currentDate = parseMonthDay(date); if (lastDate != null) { - periods.add(new Pair<>(lastDate.getDayOfYear(), currentDate.getDayOfYear())); + periods.add(new FreezePeriod(lastDate, currentDate)); lastDate = null; } else { lastDate = currentDate; @@ -457,7 +457,7 @@ public final class SystemUpdatePolicyTest { } private void testSerialization(SystemUpdatePolicy policy, - List<Pair<Integer, Integer>> expectedPeriods) throws Exception { + List<FreezePeriod> expectedPeriods) throws Exception { // Test parcel / unparcel Parcel parcel = Parcel.obtain(); policy.writeToParcel(parcel, 0); @@ -485,36 +485,27 @@ public final class SystemUpdatePolicyTest { } private void checkFreezePeriods(SystemUpdatePolicy policy, - List<Pair<Integer, Integer>> expectedPeriods) { + List<FreezePeriod> expectedPeriods) { int i = 0; - for (Pair<Integer, Integer> period : policy.getFreezePeriods()) { - assertEquals(expectedPeriods.get(i).first, period.first); - assertEquals(expectedPeriods.get(i).second, period.second); + for (FreezePeriod period : policy.getFreezePeriods()) { + assertEquals(expectedPeriods.get(i).getStart(), period.getStart()); + assertEquals(expectedPeriods.get(i).getEnd(), period.getEnd()); i++; } } - private LocalDate parseDate(String date) { - // Use leap year when parsing date string to handle "02-29", but force round down - // to Feb 28th by overriding the year to non-leap year. - final int year; - boolean monthDateOnly = false; - if (date.length() == 5) { - year = 2000; - monthDateOnly = true; - } else { - year = Integer.parseInt(date.substring(0, 4)); - date = date.substring(5); - } - LocalDate result = LocalDate.of(year, Integer.parseInt(date.substring(0, 2)), + // MonthDay is of format MM-dd + private MonthDay parseMonthDay(String date) { + return MonthDay.of(Integer.parseInt(date.substring(0, 2)), Integer.parseInt(date.substring(3, 5))); - if (monthDateOnly) { - return result.withYear(2001); - } else { - return result; - } } + // LocalDat is of format YYYY-MM-dd + private LocalDate parseLocalDate(String date) { + return parseMonthDay(date.substring(5)).atYear(Integer.parseInt(date.substring(0, 4))); + } + + private long toMillis(int year, int month, int day) { return LocalDateTime.of(year, month, day, 0, 0, 0).atZone(ZoneId.systemDefault()) .toInstant().toEpochMilli(); diff --git a/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java index 887489423b4c..5b59e607cba7 100644 --- a/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java @@ -23,19 +23,28 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 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.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; import android.app.job.JobInfo; import android.content.ComponentName; +import android.content.Context; import android.content.pm.PackageManagerInternal; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkInfo; +import android.net.NetworkInfo.DetailedState; +import android.net.NetworkPolicyManager; import android.os.Build; -import android.os.Handler; import android.os.SystemClock; -import android.support.test.runner.AndroidJUnit4; import android.util.DataUnit; import com.android.server.LocalServices; @@ -45,14 +54,26 @@ import com.android.server.job.JobSchedulerService.Constants; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import java.time.Clock; import java.time.ZoneOffset; -@RunWith(AndroidJUnit4.class) +@RunWith(MockitoJUnitRunner.class) public class ConnectivityControllerTest { + + @Mock private Context mContext; + @Mock private ConnectivityManager mConnManager; + @Mock private NetworkPolicyManager mNetPolicyManager; + @Mock private JobSchedulerService mService; + private Constants mConstants; + private static final int UID_RED = 10001; + private static final int UID_BLUE = 10002; + @Before public void setUp() throws Exception { // Assume all packages are current SDK @@ -72,6 +93,19 @@ public class ConnectivityControllerTest { // Assume default constants for now mConstants = new Constants(); + + // Get our mocks ready + when(mContext.getSystemServiceName(ConnectivityManager.class)) + .thenReturn(Context.CONNECTIVITY_SERVICE); + when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)) + .thenReturn(mConnManager); + when(mContext.getSystemServiceName(NetworkPolicyManager.class)) + .thenReturn(Context.NETWORK_POLICY_SERVICE); + when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE)) + .thenReturn(mNetPolicyManager); + when(mService.getTestableContext()).thenReturn(mContext); + when(mService.getLock()).thenReturn(mService); + when(mService.getConstants()).thenReturn(mConstants); } @Test @@ -155,6 +189,99 @@ public class ConnectivityControllerTest { } } + @Test + public void testUpdates() throws Exception { + final ArgumentCaptor<NetworkCallback> callback = ArgumentCaptor + .forClass(NetworkCallback.class); + doNothing().when(mConnManager).registerNetworkCallback(any(), callback.capture()); + + final ConnectivityController controller = new ConnectivityController(mService); + + final Network meteredNet = new Network(101); + final NetworkCapabilities meteredCaps = createCapabilities(); + final Network unmeteredNet = new Network(202); + final NetworkCapabilities unmeteredCaps = createCapabilities() + .addCapability(NET_CAPABILITY_NOT_METERED); + + final JobStatus red = createJobStatus(createJob() + .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1), 0) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED), UID_RED); + final JobStatus blue = createJobStatus(createJob() + .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1), 0) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY), UID_BLUE); + + // Pretend we're offline when job is added + { + reset(mConnManager); + answerNetwork(UID_RED, null, null); + answerNetwork(UID_BLUE, null, null); + + controller.maybeStartTrackingJobLocked(red, null); + controller.maybeStartTrackingJobLocked(blue, null); + + assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + assertFalse(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + } + + // Metered network + { + reset(mConnManager); + answerNetwork(UID_RED, meteredNet, meteredCaps); + answerNetwork(UID_BLUE, meteredNet, meteredCaps); + + callback.getValue().onCapabilitiesChanged(meteredNet, meteredCaps); + + assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + } + + // Unmetered network background + { + reset(mConnManager); + answerNetwork(UID_RED, meteredNet, meteredCaps); + answerNetwork(UID_BLUE, meteredNet, meteredCaps); + + callback.getValue().onCapabilitiesChanged(unmeteredNet, unmeteredCaps); + + assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + } + + // Lost metered network + { + reset(mConnManager); + answerNetwork(UID_RED, unmeteredNet, unmeteredCaps); + answerNetwork(UID_BLUE, unmeteredNet, unmeteredCaps); + + callback.getValue().onLost(meteredNet); + + assertTrue(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + } + + // Specific UID was blocked + { + reset(mConnManager); + answerNetwork(UID_RED, null, null); + answerNetwork(UID_BLUE, unmeteredNet, unmeteredCaps); + + callback.getValue().onCapabilitiesChanged(unmeteredNet, unmeteredCaps); + + assertFalse(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)); + } + } + + private void answerNetwork(int uid, Network net, NetworkCapabilities caps) { + when(mConnManager.getActiveNetworkForUid(eq(uid))).thenReturn(net); + when(mConnManager.getNetworkCapabilities(eq(net))).thenReturn(caps); + if (net != null) { + final NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, null, null); + ni.setDetailedState(DetailedState.CONNECTED, null, null); + when(mConnManager.getNetworkInfoForUid(eq(net), eq(uid), anyBoolean())).thenReturn(ni); + } + } + private static NetworkCapabilities createCapabilities() { return new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET) .addCapability(NET_CAPABILITY_VALIDATED); @@ -165,12 +292,22 @@ public class ConnectivityControllerTest { } private static JobStatus createJobStatus(JobInfo.Builder job) { - return createJobStatus(job, 0, Long.MAX_VALUE); + return createJobStatus(job, android.os.Process.NOBODY_UID, 0, Long.MAX_VALUE); + } + + private static JobStatus createJobStatus(JobInfo.Builder job, int uid) { + return createJobStatus(job, uid, 0, Long.MAX_VALUE); + } + + private static JobStatus createJobStatus(JobInfo.Builder job, + long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { + return createJobStatus(job, android.os.Process.NOBODY_UID, + earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis); } - private static JobStatus createJobStatus(JobInfo.Builder job, long earliestRunTimeElapsedMillis, - long latestRunTimeElapsedMillis) { - return new JobStatus(job.build(), 0, null, -1, 0, 0, null, earliestRunTimeElapsedMillis, - latestRunTimeElapsedMillis, 0, 0, null, 0); + private static JobStatus createJobStatus(JobInfo.Builder job, int uid, + long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { + return new JobStatus(job.build(), uid, null, -1, 0, 0, null, + earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis, 0, 0, null, 0); } } diff --git a/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java index 8b78f10b0b5b..164c80b2427a 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java @@ -88,4 +88,25 @@ public class AnimatingAppWindowTokenRegistryTest extends WindowTestsBase { verify(mMockEndDeferFinishCallback1).run(); verifyZeroInteractions(mMockEndDeferFinishCallback2); } + + @Test + public void testContainerRemoved() throws Exception { + final AppWindowToken window1 = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + final AppWindowToken window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD, + "window2").mAppToken; + final AnimatingAppWindowTokenRegistry registry = + window1.getStack().getAnimatingAppWindowTokenRegistry(); + + window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */); + window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */); + assertTrue(window1.isSelfAnimating()); + assertTrue(window2.isSelfAnimating()); + + // Make sure that first animation finish is deferred, and removing the second window stops + // finishes all pending deferred finishings. + registry.notifyAboutToFinish(window1, mMockEndDeferFinishCallback1); + window2.setParent(null); + verify(mMockEndDeferFinishCallback1).run(); + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java index 794d0336904a..ca520ed76be6 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java @@ -56,7 +56,8 @@ public class WindowAnimationSpecTest { Rect windowCrop = new Rect(0, 0, 20, 20); Animation a = createClipRectAnimation(windowCrop, windowCrop); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, - mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_NONE); + mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_NONE, + true /* isAppAnimation */); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(rect -> rect.equals(windowCrop))); @@ -65,7 +66,8 @@ public class WindowAnimationSpecTest { @Test public void testApply_clipAfter() { WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation, null, - mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_AFTER_ANIM); + mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_AFTER_ANIM, + true /* isAppAnimation */); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty)); verify(mTransaction).setFinalCrop(eq(mSurfaceControl), @@ -77,7 +79,8 @@ public class WindowAnimationSpecTest { // Stack bounds is (0, 0, 10, 10) position is (20, 40) WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation, new Point(20, 40), mStackBounds, false /* canSkipFirstFrame */, - STACK_CLIP_AFTER_ANIM); + STACK_CLIP_AFTER_ANIM, + true /* isAppAnimation */); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty)); verify(mTransaction).setFinalCrop(eq(mSurfaceControl), @@ -89,7 +92,8 @@ public class WindowAnimationSpecTest { public void testApply_clipBeforeNoAnimationBounds() { // Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 0, 0) WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation, null, - mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM); + mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM, + true /* isAppAnimation */); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(rect -> rect.equals(mStackBounds))); @@ -102,7 +106,8 @@ public class WindowAnimationSpecTest { Animation a = createClipRectAnimation(windowCrop, windowCrop); a.initialize(0, 0, 0, 0); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, - null, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM); + null, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM, + true /* isAppAnimation */); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty)); } @@ -113,7 +118,8 @@ public class WindowAnimationSpecTest { Rect windowCrop = new Rect(0, 0, 5, 5); Animation a = createClipRectAnimation(windowCrop, windowCrop); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, - mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM); + mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM, + true /* isAppAnimation */); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(rect -> rect.equals(windowCrop))); @@ -125,7 +131,8 @@ public class WindowAnimationSpecTest { Rect windowCrop = new Rect(0, 0, 20, 20); Animation a = createClipRectAnimation(windowCrop, windowCrop); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, - mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM); + mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM, + true /* isAppAnimation */); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(rect -> rect.equals(mStackBounds))); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java index 0f2e56b83f75..9f7205b8efc8 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java @@ -28,7 +28,7 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.app.Notification; -import android.app.Notification.Person; +import android.app.Person; import android.app.PendingIntent; import android.app.RemoteInput; import android.content.Context; @@ -193,13 +193,13 @@ public class NotificationTest extends UiServiceTestCase { Notification.Builder nM1 = new Notification.Builder(mContext, "test") .setStyle(new Notification.MessagingStyle("") .addMessage(new Notification.MessagingStyle.Message( - "a", 100, mock(Notification.Person.class)))); + "a", 100, mock(Person.class)))); Notification.Builder nM2 = new Notification.Builder(mContext, "test") .setStyle(new Notification.MessagingStyle("") .addMessage(new Notification.MessagingStyle.Message( - "a", 100, mock(Notification.Person.class))) + "a", 100, mock(Person.class))) .addMessage(new Notification.MessagingStyle.Message( - "b", 100, mock(Notification.Person.class))) + "b", 100, mock(Person.class))) ); assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nM1, nM2)); @@ -257,11 +257,11 @@ public class NotificationTest extends UiServiceTestCase { Notification.Builder nM1 = new Notification.Builder(mContext, "test") .setStyle(new Notification.MessagingStyle("") .addMessage(new Notification.MessagingStyle.Message( - "a", 100, mock(Notification.Person.class)))); + "a", 100, mock(Person.class)))); Notification.Builder nM2 = new Notification.Builder(mContext, "test") .setStyle(new Notification.MessagingStyle("") .addMessage(new Notification.MessagingStyle.Message( - "a", 1000, mock(Notification.Person.class))) + "a", 1000, mock(Person.class))) ); assertFalse(Notification.areStyledNotificationsVisiblyDifferent(nM1, nM2)); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java index a60d715c9abe..025b11a70414 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java @@ -16,6 +16,7 @@ package com.android.server.notification; import android.app.Notification; +import android.app.Person; import android.os.Bundle; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; @@ -158,10 +159,10 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase { public void testPeopleArrayList() throws Exception { Bundle bundle = new Bundle(); String[] expected = { "name:test" , "tel:1234" }; - final ArrayList<Notification.Person> arrayList = + final ArrayList<Person> arrayList = new ArrayList<>(expected.length); - arrayList.add(new Notification.Person().setName("test")); - arrayList.add(new Notification.Person().setUri(expected[1])); + arrayList.add(new Person.Builder().setName("test").build()); + arrayList.add(new Person.Builder().setUri(expected[1]).build()); bundle.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, arrayList); String[] result = ValidateNotificationPeople.getExtraPeople(bundle); assertStringArrayEquals("testPeopleArrayList", expected, result); diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index 95eb14ada354..b3a3bf21cd8b 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -129,6 +129,9 @@ public final class PhoneAccount implements Parcelable { * <p> * By default, Self-Managed {@link PhoneAccount}s do not log their calls to the call log. * Setting this extra to {@code true} provides a means for them to log their calls. + * <p> + * Note: Only calls where the {@link Call.Details#getHandle()} {@link Uri#getScheme()} is + * {@link #SCHEME_SIP} or {@link #SCHEME_TEL} will be logged at the current time. */ public static final String EXTRA_LOG_SELF_MANAGED_CALLS = "android.telecom.extra.LOG_SELF_MANAGED_CALLS"; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 288411a8186c..aa76eab89681 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -2187,7 +2187,7 @@ 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, 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); diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java index 35682a74744e..f7e6840f7580 100644 --- a/telephony/java/android/telephony/NetworkService.java +++ b/telephony/java/android/telephony/NetworkService.java @@ -206,8 +206,10 @@ public abstract class NetworkService extends Service { } } - /** @hide */ - protected NetworkService() { + /** + * Default constructor. + */ + public NetworkService() { mHandlerThread = new HandlerThread(TAG); mHandlerThread.start(); diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index e971d08aae7a..fa7988dd97b5 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -977,11 +977,13 @@ public class ServiceState implements Parcelable { } /** @hide */ + @TestApi public void setCellBandwidths(int[] bandwidths) { mCellBandwidths = bandwidths; } /** @hide */ + @TestApi public void setChannelNumber(int channelNumber) { mChannelNumber = channelNumber; } @@ -1172,6 +1174,7 @@ public class ServiceState implements Parcelable { } /** @hide */ + @TestApi public void setRilVoiceRadioTechnology(int rt) { if (rt == RIL_RADIO_TECHNOLOGY_LTE_CA) { rt = RIL_RADIO_TECHNOLOGY_LTE; @@ -1181,6 +1184,7 @@ public class ServiceState implements Parcelable { } /** @hide */ + @TestApi public void setRilDataRadioTechnology(int rt) { if (rt == RIL_RADIO_TECHNOLOGY_LTE_CA) { rt = RIL_RADIO_TECHNOLOGY_LTE; diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java index e8c1cb11c0dd..4ca5ce3004be 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -429,8 +429,10 @@ public abstract class DataService extends Service { } } - /** @hide */ - protected DataService() { + /** + * Default constructor. + */ + public DataService() { mHandlerThread = new HandlerThread(TAG); mHandlerThread.start(); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 163dd2a7e9ae..b0e11c4e8b48 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -17,6 +17,9 @@ package com.android.server; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; @@ -70,6 +73,7 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -181,6 +185,9 @@ public class ConnectivityServiceTest { private static final int TIMEOUT_MS = 500; private static final int TEST_LINGER_DELAY_MS = 120; + private static final String MOBILE_IFNAME = "test_rmnet_data0"; + private static final String WIFI_IFNAME = "test_wlan0"; + private MockContext mServiceContext; private WrappedConnectivityService mService; private WrappedConnectivityManager mCm; @@ -751,7 +758,7 @@ public class ConnectivityServiceTest { // NetworkMonitor implementation allowing overriding of Internet connectivity probe result. private class WrappedNetworkMonitor extends NetworkMonitor { - public Handler connectivityHandler; + public final Handler connectivityHandler; // HTTP response code fed back to NetworkMonitor for Internet connectivity probe. public int gen204ProbeResult = 500; public String gen204ProbeRedirectUrl = null; @@ -928,6 +935,7 @@ public class ConnectivityServiceTest { // Ensure that the default setting for Captive Portals is used for most tests setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT); setMobileDataAlwaysOn(false); + setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); } @After @@ -2582,6 +2590,14 @@ public class ConnectivityServiceTest { waitForIdle(); } + private void setPrivateDnsSettings(String mode, String specifier) { + final ContentResolver cr = mServiceContext.getContentResolver(); + Settings.Global.putString(cr, Settings.Global.PRIVATE_DNS_MODE, mode); + Settings.Global.putString(cr, Settings.Global.PRIVATE_DNS_SPECIFIER, specifier); + mService.updatePrivateDnsSettings(); + waitForIdle(); + } + private boolean isForegroundNetwork(MockNetworkAgent network) { NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); assertNotNull(nc); @@ -3583,7 +3599,7 @@ public class ConnectivityServiceTest { mCm.registerNetworkCallback(networkRequest, networkCallback); LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("wlan0"); + lp.setInterfaceName(WIFI_IFNAME); LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, NetworkUtils.numericToInetAddress("192.168.12.1"), lp.getInterfaceName()); @@ -3672,52 +3688,63 @@ public class ConnectivityServiceTest { @Test public void testBasicDnsConfigurationPushed() throws Exception { - final String IFNAME = "test_rmnet_data0"; - final String[] EMPTY_TLS_SERVERS = new String[0]; + setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); + ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class); + + // Clear any interactions that occur as a result of CS starting up. + reset(mNetworkManagementService); + + final String[] EMPTY_STRING_ARRAY = new String[0]; mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); waitForIdle(); verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork( - anyInt(), any(), any(), any(), anyString(), eq(EMPTY_TLS_SERVERS)); + anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY)); + verifyNoMoreInteractions(mNetworkManagementService); final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName(IFNAME); + cellLp.setInterfaceName(MOBILE_IFNAME); // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does // "is-reachable" testing in order to not program netd with unreachable // nameservers that it might try repeated to validate. cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); - cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), IFNAME)); + cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), + MOBILE_IFNAME)); cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); - cellLp.addRoute( - new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), IFNAME)); + cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), + MOBILE_IFNAME)); mCellNetworkAgent.sendLinkProperties(cellLp); mCellNetworkAgent.connect(false); waitForIdle(); - verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork( - anyInt(), mStringArrayCaptor.capture(), any(), any(), - anyString(), eq(EMPTY_TLS_SERVERS)); // CS tells netd about the empty DNS config for this network. - assertEmpty(mStringArrayCaptor.getValue()); + verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY)); reset(mNetworkManagementService); cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); mCellNetworkAgent.sendLinkProperties(cellLp); waitForIdle(); - verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork( + verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( anyInt(), mStringArrayCaptor.capture(), any(), any(), - anyString(), eq(EMPTY_TLS_SERVERS)); + eq(""), tlsServers.capture()); assertEquals(1, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "2001:db8::1")); + // Opportunistic mode. + assertTrue(ArrayUtils.contains(tlsServers.getValue(), "2001:db8::1")); reset(mNetworkManagementService); cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); mCellNetworkAgent.sendLinkProperties(cellLp); waitForIdle(); - verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork( + verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( anyInt(), mStringArrayCaptor.capture(), any(), any(), - anyString(), eq(EMPTY_TLS_SERVERS)); + eq(""), tlsServers.capture()); assertEquals(2, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); + // Opportunistic mode. + assertEquals(2, tlsServers.getValue().length); + assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), + new String[]{"2001:db8::1", "192.0.2.1"})); reset(mNetworkManagementService); final String TLS_SPECIFIER = "tls.example.com"; @@ -3730,7 +3757,7 @@ public class ConnectivityServiceTest { mCellNetworkAgent.getNetwork().netId, new DnsManager.PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS))); waitForIdle(); - verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork( + verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( anyInt(), mStringArrayCaptor.capture(), any(), any(), eq(TLS_SPECIFIER), eq(TLS_SERVERS)); assertEquals(2, mStringArrayCaptor.getValue().length); @@ -3739,6 +3766,77 @@ public class ConnectivityServiceTest { reset(mNetworkManagementService); } + @Test + public void testPrivateDnsSettingsChange() throws Exception { + final String[] EMPTY_STRING_ARRAY = new String[0]; + ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class); + + // Clear any interactions that occur as a result of CS starting up. + reset(mNetworkManagementService); + + // The default on Android is opportunistic mode ("Automatic"). + setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); + + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + waitForIdle(); + // CS tells netd about the empty DNS config for this network. + verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork( + anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY)); + verifyNoMoreInteractions(mNetworkManagementService); + + final LinkProperties cellLp = new LinkProperties(); + cellLp.setInterfaceName(MOBILE_IFNAME); + // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does + // "is-reachable" testing in order to not program netd with unreachable + // nameservers that it might try repeated to validate. + cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); + cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), + MOBILE_IFNAME)); + cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); + cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), + MOBILE_IFNAME)); + cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); + cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); + + mCellNetworkAgent.sendLinkProperties(cellLp); + mCellNetworkAgent.connect(false); + waitForIdle(); + verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + anyInt(), mStringArrayCaptor.capture(), any(), any(), + eq(""), tlsServers.capture()); + assertEquals(2, mStringArrayCaptor.getValue().length); + assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), + new String[]{"2001:db8::1", "192.0.2.1"})); + // Opportunistic mode. + assertEquals(2, tlsServers.getValue().length); + assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), + new String[]{"2001:db8::1", "192.0.2.1"})); + reset(mNetworkManagementService); + + setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); + verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork( + anyInt(), mStringArrayCaptor.capture(), any(), any(), + eq(""), eq(EMPTY_STRING_ARRAY)); + assertEquals(2, mStringArrayCaptor.getValue().length); + assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), + new String[]{"2001:db8::1", "192.0.2.1"})); + reset(mNetworkManagementService); + + setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); + verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + anyInt(), mStringArrayCaptor.capture(), any(), any(), + eq(""), tlsServers.capture()); + assertEquals(2, mStringArrayCaptor.getValue().length); + assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), + new String[]{"2001:db8::1", "192.0.2.1"})); + assertEquals(2, tlsServers.getValue().length); + assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), + new String[]{"2001:db8::1", "192.0.2.1"})); + reset(mNetworkManagementService); + + // Can't test strict mode without properly mocking out the DNS lookups. + } + private void checkDirectlyConnectedRoutes(Object callbackObj, Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { assertTrue(callbackObj instanceof LinkProperties); diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 2f7b50d1bd0c..b3331264aa17 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -143,7 +143,7 @@ interface IWifiManager WifiConfiguration getWifiApConfiguration(); - void setWifiApConfiguration(in WifiConfiguration wifiConfig, String packageName); + boolean setWifiApConfiguration(in WifiConfiguration wifiConfig, String packageName); Messenger getWifiServiceMessenger(String packageName); diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index b77b1ad5f255..f6c67c93e773 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -28,10 +28,12 @@ import android.net.Uri; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; +import android.os.SystemClock; import android.os.UserHandle; import android.text.TextUtils; import android.util.BackupUtils; import android.util.Log; +import android.util.TimeUtils; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -611,37 +613,6 @@ public class WifiConfiguration implements Parcelable { /** * @hide - * Last time the system tried to connect and failed. - */ - public long lastConnectionFailure; - - /** - * @hide - * Last time the system tried to roam and failed because of authentication failure or DHCP - * RENEW failure. - */ - public long lastRoamingFailure; - - /** @hide */ - public static int ROAMING_FAILURE_IP_CONFIG = 1; - /** @hide */ - public static int ROAMING_FAILURE_AUTH_FAILURE = 2; - - /** - * @hide - * Initial amount of time this Wifi configuration gets blacklisted for network switching - * because of roaming failure - */ - public long roamingFailureBlackListTimeMilli = 1000; - - /** - * @hide - * Last roaming failure reason code - */ - public int lastRoamingFailureReason; - - /** - * @hide * Last time the system was disconnected to this configuration. */ public long lastDisconnected; @@ -1620,8 +1591,9 @@ public class WifiConfiguration implements Parcelable { } if (mNetworkSelectionStatus.getConnectChoice() != null) { sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice()); - sbuf.append(" connect choice set time: ").append(mNetworkSelectionStatus - .getConnectChoiceTimestamp()); + sbuf.append(" connect choice set time: ") + .append(TimeUtils.logTimeOfDay( + mNetworkSelectionStatus.getConnectChoiceTimestamp())); } sbuf.append(" hasEverConnected: ") .append(mNetworkSelectionStatus.getHasEverConnected()).append("\n"); @@ -1724,7 +1696,7 @@ public class WifiConfiguration implements Parcelable { sbuf.append(" networkSelectionBSSID=" + mNetworkSelectionStatus.getNetworkSelectionBSSID()); } - long now_ms = System.currentTimeMillis(); + long now_ms = SystemClock.elapsedRealtime(); if (mNetworkSelectionStatus.getDisableTime() != NetworkSelectionStatus .INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP) { sbuf.append('\n'); @@ -1746,35 +1718,9 @@ public class WifiConfiguration implements Parcelable { if (this.lastConnected != 0) { sbuf.append('\n'); - long diff = now_ms - this.lastConnected; - if (diff <= 0) { - sbuf.append("lastConnected since <incorrect>"); - } else { - sbuf.append("lastConnected: ").append(Long.toString(diff / 1000)).append("sec "); - } - } - if (this.lastConnectionFailure != 0) { - sbuf.append('\n'); - long diff = now_ms - this.lastConnectionFailure; - if (diff <= 0) { - sbuf.append("lastConnectionFailure since <incorrect> "); - } else { - sbuf.append("lastConnectionFailure: ").append(Long.toString(diff / 1000)); - sbuf.append("sec "); - } - } - if (this.lastRoamingFailure != 0) { - sbuf.append('\n'); - long diff = now_ms - this.lastRoamingFailure; - if (diff <= 0) { - sbuf.append("lastRoamingFailure since <incorrect> "); - } else { - sbuf.append("lastRoamingFailure: ").append(Long.toString(diff / 1000)); - sbuf.append("sec "); - } + sbuf.append("lastConnected: ").append(TimeUtils.logTimeOfDay(this.lastConnected)); + sbuf.append(" "); } - sbuf.append("roamingFailureBlackListTimeMilli: "). - append(Long.toString(this.roamingFailureBlackListTimeMilli)); sbuf.append('\n'); if (this.linkedConfigurations != null) { for (String key : this.linkedConfigurations.keySet()) { @@ -2119,10 +2065,6 @@ public class WifiConfiguration implements Parcelable { lastConnected = source.lastConnected; lastDisconnected = source.lastDisconnected; - lastConnectionFailure = source.lastConnectionFailure; - lastRoamingFailure = source.lastRoamingFailure; - lastRoamingFailureReason = source.lastRoamingFailureReason; - roamingFailureBlackListTimeMilli = source.roamingFailureBlackListTimeMilli; numScorerOverride = source.numScorerOverride; numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; numAssociation = source.numAssociation; @@ -2188,10 +2130,6 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(lastUpdateUid); dest.writeString(creatorName); dest.writeString(lastUpdateName); - dest.writeLong(lastConnectionFailure); - dest.writeLong(lastRoamingFailure); - dest.writeInt(lastRoamingFailureReason); - dest.writeLong(roamingFailureBlackListTimeMilli); dest.writeInt(numScorerOverride); dest.writeInt(numScorerOverrideAndSwitchedNetwork); dest.writeInt(numAssociation); @@ -2257,10 +2195,6 @@ public class WifiConfiguration implements Parcelable { config.lastUpdateUid = in.readInt(); config.creatorName = in.readString(); config.lastUpdateName = in.readString(); - config.lastConnectionFailure = in.readLong(); - config.lastRoamingFailure = in.readLong(); - config.lastRoamingFailureReason = in.readInt(); - config.roamingFailureBlackListTimeMilli = in.readLong(); config.numScorerOverride = in.readInt(); config.numScorerOverrideAndSwitchedNetwork = in.readInt(); config.numAssociation = in.readInt(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 433285bfc702..9c6c8a90369d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2141,7 +2141,8 @@ public class WifiManager { } /** - * Sets the Wi-Fi AP Configuration. + * Sets the Wi-Fi AP Configuration. The AP configuration must either be open or + * WPA2 PSK networks. * @return {@code true} if the operation succeeded, {@code false} otherwise * * @hide @@ -2150,8 +2151,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { try { - mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); - return true; + return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index f3a78bd01cbe..f3ffcadf2546 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1034,4 +1034,40 @@ i * Verify that a call to cancel WPS immediately returns a failure. verifyNoMoreInteractions(mWifiService); } + /** + * Verify that a successful call properly returns true. + */ + @Test + public void testSetWifiApConfigurationSuccessReturnsTrue() throws Exception { + WifiConfiguration apConfig = new WifiConfiguration(); + + when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) + .thenReturn(true); + assertTrue(mWifiManager.setWifiApConfiguration(apConfig)); + } + + /** + * Verify that a failed call properly returns false. + */ + @Test + public void testSetWifiApConfigurationFailureReturnsFalse() throws Exception { + WifiConfiguration apConfig = new WifiConfiguration(); + + when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) + .thenReturn(false); + assertFalse(mWifiManager.setWifiApConfiguration(apConfig)); + } + + /** + * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions. + */ + @Test + public void testSetWifiApConfigurationRethrowsException() throws Exception { + doThrow(new SecurityException()).when(mWifiService).setWifiApConfiguration(any(), any()); + + try { + mWifiManager.setWifiApConfiguration(new WifiConfiguration()); + fail("setWifiApConfiguration should rethrow Exceptions from WifiService"); + } catch (SecurityException e) { } + } } |