Merge "Document examples where a developer might use the APIs." into oc-dev
diff --git a/api/current.txt b/api/current.txt
index ed83811..0873990 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -210,6 +210,7 @@
public static final class R.attr {
ctor public R.attr();
field public static final int __removed1 = 16844099; // 0x1010543
+ field public static final int __removed2 = 16844104; // 0x1010548
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -471,6 +472,7 @@
field public static final deprecated int dayOfWeekBackground = 16843924; // 0x1010494
field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
field public static final int debuggable = 16842767; // 0x101000f
+ field public static final int defaultFocusHighlightEnabled = 16844133; // 0x1010565
field public static final int defaultHeight = 16844021; // 0x10104f5
field public static final int defaultToDeviceProtectedStorage = 16844036; // 0x1010504
field public static final int defaultValue = 16843245; // 0x10101ed
@@ -1269,7 +1271,6 @@
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
field public static final int supportsAssist = 16844016; // 0x10104f0
- field public static final int supportsDismissingWindow = 16844104; // 0x1010548
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
field public static final int supportsPictureInPicture = 16844023; // 0x10104f7
@@ -1951,6 +1952,7 @@
field public static final int no = 17039369; // 0x1040009
field public static final int ok = 17039370; // 0x104000a
field public static final int paste = 17039371; // 0x104000b
+ field public static final int paste_as_plain_text = 17039385; // 0x1040019
field public static final int search_go = 17039372; // 0x104000c
field public static final int selectAll = 17039373; // 0x104000d
field public static final int selectTextMode = 17039382; // 0x1040016
@@ -6826,6 +6828,8 @@
}
public class JobParameters implements android.os.Parcelable {
+ method public void completeWork(android.app.job.JobWorkItem);
+ method public android.app.job.JobWorkItem dequeueWork();
method public int describeContents();
method public android.content.ClipData getClipData();
method public int getClipGrantFlags();
@@ -6843,6 +6847,7 @@
ctor public JobScheduler();
method public abstract void cancel(int);
method public abstract void cancelAll();
+ method public abstract int enqueue(android.app.job.JobInfo, android.app.job.JobWorkItem);
method public abstract java.util.List<android.app.job.JobInfo> getAllPendingJobs();
method public abstract android.app.job.JobInfo getPendingJob(int);
method public abstract int schedule(android.app.job.JobInfo);
@@ -6859,6 +6864,15 @@
field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_JOB_SERVICE";
}
+ public final class JobWorkItem implements android.os.Parcelable {
+ ctor public JobWorkItem(android.content.Intent);
+ ctor public JobWorkItem(android.os.Parcel);
+ method public int describeContents();
+ method public android.content.Intent getIntent();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.job.JobWorkItem> CREATOR;
+ }
+
}
package android.app.usage {
@@ -10619,6 +10633,7 @@
field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
field public static final java.lang.String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
field public static final java.lang.String FEATURE_AUDIO_PRO = "android.hardware.audio.pro";
+ field public static final java.lang.String FEATURE_AUTOFILL = "android.software.autofill";
field public static final java.lang.String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
field public static final java.lang.String FEATURE_BACKUP = "android.software.backup";
field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
@@ -13768,23 +13783,16 @@
}
public static final class Typeface.Builder {
- ctor public Typeface.Builder();
+ ctor public Typeface.Builder(java.io.File);
+ ctor public Typeface.Builder(java.io.FileDescriptor);
+ ctor public Typeface.Builder(java.lang.String);
+ ctor public Typeface.Builder(android.content.res.AssetManager, java.lang.String);
method public android.graphics.Typeface build();
- method public static android.graphics.Typeface.Builder obtain();
- method public void recycle();
- method public void reset();
method public android.graphics.Typeface.Builder setFontVariationSettings(java.lang.String) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
method public android.graphics.Typeface.Builder setFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
- method public android.graphics.Typeface.Builder setItalic(int);
- method public android.graphics.Typeface.Builder setSourceFromAsset(android.content.res.AssetManager, java.lang.String);
- method public android.graphics.Typeface.Builder setSourceFromFile(java.io.File);
- method public android.graphics.Typeface.Builder setSourceFromFile(java.io.FileDescriptor);
- method public android.graphics.Typeface.Builder setSourceFromFilePath(java.lang.String);
+ method public android.graphics.Typeface.Builder setItalic(boolean);
method public android.graphics.Typeface.Builder setTtcIndex(int);
method public android.graphics.Typeface.Builder setWeight(int);
- field public static final int ITALIC = 1; // 0x1
- field public static final int NORMAL = 0; // 0x0
- field public static final int RESOLVE_BY_FONT_TABLE = -1; // 0xffffffff
}
public static abstract interface Typeface.FontRequestCallback {
@@ -14384,15 +14392,12 @@
field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontRequest> CREATOR;
}
- public final class FontVariationAxis implements android.os.Parcelable {
+ public final class FontVariationAxis {
ctor public FontVariationAxis(java.lang.String, float) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
- method public int describeContents();
method public static android.graphics.fonts.FontVariationAxis[] fromFontVariationSettings(java.lang.String) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
method public float getStyleValue();
method public java.lang.String getTag();
method public static java.lang.String toFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontVariationAxis> CREATOR;
}
public static class FontVariationAxis.InvalidFormatException extends java.lang.Exception {
@@ -21805,24 +21810,19 @@
field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
}
- public final class MediaCas {
+ public final class MediaCas implements java.lang.AutoCloseable {
ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
- method public void closeSession(byte[]);
+ method public void close();
method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
method public static boolean isSystemIdSupported(int);
- method public byte[] openSession(int) throws android.media.MediaCasException;
- method public byte[] openSession(int, int) throws android.media.MediaCasException;
- method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
- method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
+ method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
method public void processEmm(byte[]) throws android.media.MediaCasException;
method public void provision(java.lang.String) throws android.media.MediaCasException;
method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
- method public void release();
method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
method public void setPrivateData(byte[]) throws android.media.MediaCasException;
- method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
}
public static abstract interface MediaCas.EventListener {
@@ -21834,6 +21834,13 @@
method public int getSystemId();
}
+ public final class MediaCas.Session implements java.lang.AutoCloseable {
+ method public void close();
+ method public void processEcm(byte[], int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[]) throws android.media.MediaCasException;
+ method public void setPrivateData(byte[]) throws android.media.MediaCasException;
+ }
+
public class MediaCasException extends java.lang.Exception {
}
@@ -22277,12 +22284,12 @@
method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
}
- public final class MediaDescrambler {
+ public final class MediaDescrambler implements java.lang.AutoCloseable {
ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
- method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
- method public final void release();
+ method public void close();
+ method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
method public final boolean requiresSecureDecoderComponent(java.lang.String);
- method public final void setMediaCasSession(byte[]);
+ method public final void setMediaCasSession(android.media.MediaCas.Session);
}
public class MediaDescription implements android.os.Parcelable {
@@ -22420,6 +22427,7 @@
ctor public MediaExtractor();
method public boolean advance();
method public long getCachedDuration();
+ method public android.media.MediaExtractor.CasInfo getCasInfo(int);
method public android.media.DrmInitData getDrmInitData();
method public android.media.MediaMetricsSet getMetrics();
method public java.util.Map<java.util.UUID, byte[]> getPsshInfo();
@@ -22451,6 +22459,11 @@
field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
}
+ public static final class MediaExtractor.CasInfo {
+ method public android.media.MediaCas.Session getSession();
+ method public int getSystemId();
+ }
+
public final class MediaFormat {
ctor public MediaFormat();
method public final boolean containsKey(java.lang.String);
@@ -23619,7 +23632,7 @@
public static final class VolumeShaper.Configuration implements android.os.Parcelable {
method public int describeContents();
- method public double getDurationMs();
+ method public double getDurationMillis();
method public int getInterpolatorType();
method public static int getMaximumCurvePoints();
method public float[] getTimes();
@@ -23645,7 +23658,7 @@
method public android.media.VolumeShaper.Configuration.Builder scaleToEndVolume(float);
method public android.media.VolumeShaper.Configuration.Builder scaleToStartVolume(float);
method public android.media.VolumeShaper.Configuration.Builder setCurve(float[], float[]);
- method public android.media.VolumeShaper.Configuration.Builder setDurationMs(double);
+ method public android.media.VolumeShaper.Configuration.Builder setDurationMillis(double);
method public android.media.VolumeShaper.Configuration.Builder setInterpolatorType(int);
}
@@ -24704,6 +24717,8 @@
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+ field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+ field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
@@ -24718,6 +24733,9 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
+ field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+ field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+ field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
}
public static final class TvContract.Programs.Genres {
@@ -24764,6 +24782,8 @@
field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+ field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+ field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
@@ -24777,6 +24797,9 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
field public static final android.net.Uri CONTENT_URI;
+ field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+ field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+ field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
}
public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
@@ -34478,10 +34501,14 @@
}
public class FontsContract {
+ method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String);
+ method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]);
+ method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
}
public static final class FontsContract.Columns implements android.provider.BaseColumns {
ctor public FontsContract.Columns();
+ field public static final java.lang.String FILE_ID = "file_id";
field public static final java.lang.String ITALIC = "font_italic";
field public static final java.lang.String RESULT_CODE = "result_code";
field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
@@ -34493,6 +34520,23 @@
field public static final java.lang.String WEIGHT = "font_weight";
}
+ public static class FontsContract.FontFamilyResult {
+ method public android.provider.FontsContract.FontInfo[] getFonts();
+ method public int getStatusCode();
+ field public static final int STATUS_OK = 0; // 0x0
+ field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
+ field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
+ }
+
+ public static class FontsContract.FontInfo {
+ method public android.graphics.fonts.FontVariationAxis[] getAxes();
+ method public int getResultCode();
+ method public int getTtcIndex();
+ method public android.net.Uri getUri();
+ method public int getWeight();
+ method public boolean isItalic();
+ }
+
public final deprecated class LiveFolders implements android.provider.BaseColumns {
field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER";
field public static final java.lang.String DESCRIPTION = "description";
@@ -40105,7 +40149,8 @@
method public boolean hasIccCard();
method public boolean iccCloseLogicalChannel(int);
method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
- method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
+ method public deprecated android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
+ method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String, int);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
method public boolean isConcurrentVoiceAndDataSupported();
@@ -42616,7 +42661,7 @@
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;
@@ -45327,6 +45372,7 @@
method public java.lang.CharSequence getContentDescription();
method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
+ method public final boolean getDefaultFocusHighlightEnabled();
method public static int getDefaultSize(int, int);
method public android.view.Display getDisplay();
method public final int[] getDrawableState();
@@ -45645,6 +45691,7 @@
method public void setClipToOutline(boolean);
method public void setContentDescription(java.lang.CharSequence);
method public void setContextClickable(boolean);
+ method public void setDefaultFocusHighlightEnabled(boolean);
method public void setDrawingCacheBackgroundColor(int);
method public void setDrawingCacheEnabled(boolean);
method public void setDrawingCacheQuality(int);
@@ -48886,7 +48933,7 @@
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);
diff --git a/api/system-current.txt b/api/system-current.txt
index 3a9e410..5cd3b0a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -326,6 +326,7 @@
public static final class R.attr {
ctor public R.attr();
field public static final int __removed1 = 16844099; // 0x1010543
+ field public static final int __removed2 = 16844104; // 0x1010548
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -587,6 +588,7 @@
field public static final deprecated int dayOfWeekBackground = 16843924; // 0x1010494
field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
field public static final int debuggable = 16842767; // 0x101000f
+ field public static final int defaultFocusHighlightEnabled = 16844133; // 0x1010565
field public static final int defaultHeight = 16844021; // 0x10104f5
field public static final int defaultToDeviceProtectedStorage = 16844036; // 0x1010504
field public static final int defaultValue = 16843245; // 0x10101ed
@@ -1389,7 +1391,6 @@
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
field public static final int supportsAssist = 16844016; // 0x10104f0
- field public static final int supportsDismissingWindow = 16844104; // 0x1010548
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
field public static final int supportsPictureInPicture = 16844023; // 0x10104f7
@@ -2073,6 +2074,7 @@
field public static final int no = 17039369; // 0x1040009
field public static final int ok = 17039370; // 0x104000a
field public static final int paste = 17039371; // 0x104000b
+ field public static final int paste_as_plain_text = 17039385; // 0x1040019
field public static final int search_go = 17039372; // 0x104000c
field public static final int selectAll = 17039373; // 0x104000d
field public static final int selectTextMode = 17039382; // 0x1040016
@@ -3981,6 +3983,7 @@
method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException;
method public java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException;
method public deprecated java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+ method public int getUidImportance(int);
method public deprecated boolean isInLockTaskMode();
method public boolean isLowRamDevice();
method public static boolean isRunningInTestHarness();
@@ -7256,6 +7259,8 @@
}
public class JobParameters implements android.os.Parcelable {
+ method public void completeWork(android.app.job.JobWorkItem);
+ method public android.app.job.JobWorkItem dequeueWork();
method public int describeContents();
method public android.content.ClipData getClipData();
method public int getClipGrantFlags();
@@ -7273,6 +7278,7 @@
ctor public JobScheduler();
method public abstract void cancel(int);
method public abstract void cancelAll();
+ method public abstract int enqueue(android.app.job.JobInfo, android.app.job.JobWorkItem);
method public abstract java.util.List<android.app.job.JobInfo> getAllPendingJobs();
method public abstract android.app.job.JobInfo getPendingJob(int);
method public abstract int schedule(android.app.job.JobInfo);
@@ -7290,6 +7296,15 @@
field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_JOB_SERVICE";
}
+ public final class JobWorkItem implements android.os.Parcelable {
+ ctor public JobWorkItem(android.content.Intent);
+ ctor public JobWorkItem(android.os.Parcel);
+ method public int describeContents();
+ method public android.content.Intent getIntent();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.job.JobWorkItem> CREATOR;
+ }
+
}
package android.app.usage {
@@ -9796,6 +9811,7 @@
field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED";
field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED";
field public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE";
+ field public static final deprecated java.lang.String ACTION_DEVICE_INITIALIZATION_WIZARD = "android.intent.action.DEVICE_INITIALIZATION_WIZARD";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK";
field public static final java.lang.String ACTION_DIAL = "android.intent.action.DIAL";
@@ -9903,6 +9919,7 @@
field public static final deprecated java.lang.String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED";
field public static final deprecated java.lang.String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED";
field public static final java.lang.String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
+ field public static final java.lang.String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP";
field public static final java.lang.String ACTION_USER_BACKGROUND = "android.intent.action.USER_BACKGROUND";
field public static final java.lang.String ACTION_USER_FOREGROUND = "android.intent.action.USER_FOREGROUND";
field public static final java.lang.String ACTION_USER_INITIALIZE = "android.intent.action.USER_INITIALIZE";
@@ -11304,6 +11321,7 @@
field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
field public static final java.lang.String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
field public static final java.lang.String FEATURE_AUDIO_PRO = "android.hardware.audio.pro";
+ field public static final java.lang.String FEATURE_AUTOFILL = "android.software.autofill";
field public static final java.lang.String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
field public static final java.lang.String FEATURE_BACKUP = "android.software.backup";
field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
@@ -14532,23 +14550,16 @@
}
public static final class Typeface.Builder {
- ctor public Typeface.Builder();
+ ctor public Typeface.Builder(java.io.File);
+ ctor public Typeface.Builder(java.io.FileDescriptor);
+ ctor public Typeface.Builder(java.lang.String);
+ ctor public Typeface.Builder(android.content.res.AssetManager, java.lang.String);
method public android.graphics.Typeface build();
- method public static android.graphics.Typeface.Builder obtain();
- method public void recycle();
- method public void reset();
method public android.graphics.Typeface.Builder setFontVariationSettings(java.lang.String) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
method public android.graphics.Typeface.Builder setFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
- method public android.graphics.Typeface.Builder setItalic(int);
- method public android.graphics.Typeface.Builder setSourceFromAsset(android.content.res.AssetManager, java.lang.String);
- method public android.graphics.Typeface.Builder setSourceFromFile(java.io.File);
- method public android.graphics.Typeface.Builder setSourceFromFile(java.io.FileDescriptor);
- method public android.graphics.Typeface.Builder setSourceFromFilePath(java.lang.String);
+ method public android.graphics.Typeface.Builder setItalic(boolean);
method public android.graphics.Typeface.Builder setTtcIndex(int);
method public android.graphics.Typeface.Builder setWeight(int);
- field public static final int ITALIC = 1; // 0x1
- field public static final int NORMAL = 0; // 0x0
- field public static final int RESOLVE_BY_FONT_TABLE = -1; // 0xffffffff
}
public static abstract interface Typeface.FontRequestCallback {
@@ -15148,15 +15159,12 @@
field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontRequest> CREATOR;
}
- public final class FontVariationAxis implements android.os.Parcelable {
+ public final class FontVariationAxis {
ctor public FontVariationAxis(java.lang.String, float) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
- method public int describeContents();
method public static android.graphics.fonts.FontVariationAxis[] fromFontVariationSettings(java.lang.String) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
method public float getStyleValue();
method public java.lang.String getTag();
method public static java.lang.String toFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontVariationAxis> CREATOR;
}
public static class FontVariationAxis.InvalidFormatException extends java.lang.Exception {
@@ -23631,24 +23639,19 @@
field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
}
- public final class MediaCas {
+ public final class MediaCas implements java.lang.AutoCloseable {
ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
- method public void closeSession(byte[]);
+ method public void close();
method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
method public static boolean isSystemIdSupported(int);
- method public byte[] openSession(int) throws android.media.MediaCasException;
- method public byte[] openSession(int, int) throws android.media.MediaCasException;
- method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
- method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
+ method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
method public void processEmm(byte[]) throws android.media.MediaCasException;
method public void provision(java.lang.String) throws android.media.MediaCasException;
method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
- method public void release();
method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
method public void setPrivateData(byte[]) throws android.media.MediaCasException;
- method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
}
public static abstract interface MediaCas.EventListener {
@@ -23660,6 +23663,13 @@
method public int getSystemId();
}
+ public final class MediaCas.Session implements java.lang.AutoCloseable {
+ method public void close();
+ method public void processEcm(byte[], int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[]) throws android.media.MediaCasException;
+ method public void setPrivateData(byte[]) throws android.media.MediaCasException;
+ }
+
public class MediaCasException extends java.lang.Exception {
}
@@ -24103,12 +24113,12 @@
method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
}
- public final class MediaDescrambler {
+ public final class MediaDescrambler implements java.lang.AutoCloseable {
ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
- method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
- method public final void release();
+ method public void close();
+ method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
method public final boolean requiresSecureDecoderComponent(java.lang.String);
- method public final void setMediaCasSession(byte[]);
+ method public final void setMediaCasSession(android.media.MediaCas.Session);
}
public class MediaDescription implements android.os.Parcelable {
@@ -24246,6 +24256,7 @@
ctor public MediaExtractor();
method public boolean advance();
method public long getCachedDuration();
+ method public android.media.MediaExtractor.CasInfo getCasInfo(int);
method public android.media.DrmInitData getDrmInitData();
method public android.media.MediaMetricsSet getMetrics();
method public java.util.Map<java.util.UUID, byte[]> getPsshInfo();
@@ -24277,6 +24288,11 @@
field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
}
+ public static final class MediaExtractor.CasInfo {
+ method public android.media.MediaCas.Session getSession();
+ method public int getSystemId();
+ }
+
public final class MediaFormat {
ctor public MediaFormat();
method public final boolean containsKey(java.lang.String);
@@ -25456,7 +25472,7 @@
public static final class VolumeShaper.Configuration implements android.os.Parcelable {
method public int describeContents();
- method public double getDurationMs();
+ method public double getDurationMillis();
method public int getInterpolatorType();
method public static int getMaximumCurvePoints();
method public float[] getTimes();
@@ -25482,7 +25498,7 @@
method public android.media.VolumeShaper.Configuration.Builder scaleToEndVolume(float);
method public android.media.VolumeShaper.Configuration.Builder scaleToStartVolume(float);
method public android.media.VolumeShaper.Configuration.Builder setCurve(float[], float[]);
- method public android.media.VolumeShaper.Configuration.Builder setDurationMs(double);
+ method public android.media.VolumeShaper.Configuration.Builder setDurationMillis(double);
method public android.media.VolumeShaper.Configuration.Builder setInterpolatorType(int);
}
@@ -26682,6 +26698,8 @@
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+ field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+ field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
@@ -26696,6 +26714,9 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
+ field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+ field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+ field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
}
public static final class TvContract.Programs.Genres {
@@ -26742,6 +26763,8 @@
field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+ field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+ field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
@@ -26755,6 +26778,9 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
field public static final android.net.Uri CONTENT_URI;
+ field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+ field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+ field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
}
public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
@@ -37452,10 +37478,14 @@
}
public class FontsContract {
+ method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String);
+ method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]);
+ method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
}
public static final class FontsContract.Columns implements android.provider.BaseColumns {
ctor public FontsContract.Columns();
+ field public static final java.lang.String FILE_ID = "file_id";
field public static final java.lang.String ITALIC = "font_italic";
field public static final java.lang.String RESULT_CODE = "result_code";
field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
@@ -37467,6 +37497,23 @@
field public static final java.lang.String WEIGHT = "font_weight";
}
+ public static class FontsContract.FontFamilyResult {
+ method public android.provider.FontsContract.FontInfo[] getFonts();
+ method public int getStatusCode();
+ field public static final int STATUS_OK = 0; // 0x0
+ field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
+ field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
+ }
+
+ public static class FontsContract.FontInfo {
+ method public android.graphics.fonts.FontVariationAxis[] getAxes();
+ method public int getResultCode();
+ method public int getTtcIndex();
+ method public android.net.Uri getUri();
+ method public int getWeight();
+ method public boolean isItalic();
+ }
+
public final deprecated class LiveFolders implements android.provider.BaseColumns {
field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER";
field public static final java.lang.String DESCRIPTION = "description";
@@ -38115,6 +38162,7 @@
field public static final deprecated java.lang.String HTTP_PROXY = "http_proxy";
field public static final java.lang.String INPUT_METHOD_SELECTOR_VISIBILITY = "input_method_selector_visibility";
field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
+ field public static final java.lang.String INSTANT_APPS_ENABLED = "instant_apps_enabled";
field public static final java.lang.String LOCATION_MODE = "location_mode";
field public static final int LOCATION_MODE_BATTERY_SAVING = 2; // 0x2
field public static final int LOCATION_MODE_HIGH_ACCURACY = 3; // 0x3
@@ -43601,7 +43649,8 @@
method public boolean hasIccCard();
method public boolean iccCloseLogicalChannel(int);
method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
- method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
+ method public deprecated android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
+ method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String, int);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
method public boolean isConcurrentVoiceAndDataSupported();
@@ -46168,7 +46217,7 @@
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;
@@ -48880,6 +48929,7 @@
method public java.lang.CharSequence getContentDescription();
method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
+ method public final boolean getDefaultFocusHighlightEnabled();
method public static int getDefaultSize(int, int);
method public android.view.Display getDisplay();
method public final int[] getDrawableState();
@@ -49198,6 +49248,7 @@
method public void setClipToOutline(boolean);
method public void setContentDescription(java.lang.CharSequence);
method public void setContextClickable(boolean);
+ method public void setDefaultFocusHighlightEnabled(boolean);
method public void setDrawingCacheBackgroundColor(int);
method public void setDrawingCacheEnabled(boolean);
method public void setDrawingCacheQuality(int);
@@ -52535,7 +52586,7 @@
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);
diff --git a/api/test-current.txt b/api/test-current.txt
index f8eefa9..c65d8da 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -210,6 +210,7 @@
public static final class R.attr {
ctor public R.attr();
field public static final int __removed1 = 16844099; // 0x1010543
+ field public static final int __removed2 = 16844104; // 0x1010548
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -471,6 +472,7 @@
field public static final deprecated int dayOfWeekBackground = 16843924; // 0x1010494
field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
field public static final int debuggable = 16842767; // 0x101000f
+ field public static final int defaultFocusHighlightEnabled = 16844133; // 0x1010565
field public static final int defaultHeight = 16844021; // 0x10104f5
field public static final int defaultToDeviceProtectedStorage = 16844036; // 0x1010504
field public static final int defaultValue = 16843245; // 0x10101ed
@@ -1269,7 +1271,6 @@
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
field public static final int supportsAssist = 16844016; // 0x10104f0
- field public static final int supportsDismissingWindow = 16844104; // 0x1010548
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
field public static final int supportsPictureInPicture = 16844023; // 0x10104f7
@@ -1951,6 +1952,7 @@
field public static final int no = 17039369; // 0x1040009
field public static final int ok = 17039370; // 0x104000a
field public static final int paste = 17039371; // 0x104000b
+ field public static final int paste_as_plain_text = 17039385; // 0x1040019
field public static final int search_go = 17039372; // 0x104000c
field public static final int selectAll = 17039373; // 0x104000d
field public static final int selectTextMode = 17039382; // 0x1040016
@@ -3848,6 +3850,7 @@
method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException;
method public java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException;
method public deprecated java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+ method public int getUidImportance(int);
method public deprecated boolean isInLockTaskMode();
method public boolean isLowRamDevice();
method public static boolean isRunningInTestHarness();
@@ -6855,6 +6858,8 @@
}
public class JobParameters implements android.os.Parcelable {
+ method public void completeWork(android.app.job.JobWorkItem);
+ method public android.app.job.JobWorkItem dequeueWork();
method public int describeContents();
method public android.content.ClipData getClipData();
method public int getClipGrantFlags();
@@ -6872,6 +6877,7 @@
ctor public JobScheduler();
method public abstract void cancel(int);
method public abstract void cancelAll();
+ method public abstract int enqueue(android.app.job.JobInfo, android.app.job.JobWorkItem);
method public abstract java.util.List<android.app.job.JobInfo> getAllPendingJobs();
method public abstract android.app.job.JobInfo getPendingJob(int);
method public abstract int schedule(android.app.job.JobInfo);
@@ -6888,6 +6894,15 @@
field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_JOB_SERVICE";
}
+ public final class JobWorkItem implements android.os.Parcelable {
+ ctor public JobWorkItem(android.content.Intent);
+ ctor public JobWorkItem(android.os.Parcel);
+ method public int describeContents();
+ method public android.content.Intent getIntent();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.job.JobWorkItem> CREATOR;
+ }
+
}
package android.app.usage {
@@ -10658,6 +10673,7 @@
field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
field public static final java.lang.String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
field public static final java.lang.String FEATURE_AUDIO_PRO = "android.hardware.audio.pro";
+ field public static final java.lang.String FEATURE_AUTOFILL = "android.software.autofill";
field public static final java.lang.String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
field public static final java.lang.String FEATURE_BACKUP = "android.software.backup";
field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
@@ -13818,23 +13834,16 @@
}
public static final class Typeface.Builder {
- ctor public Typeface.Builder();
+ ctor public Typeface.Builder(java.io.File);
+ ctor public Typeface.Builder(java.io.FileDescriptor);
+ ctor public Typeface.Builder(java.lang.String);
+ ctor public Typeface.Builder(android.content.res.AssetManager, java.lang.String);
method public android.graphics.Typeface build();
- method public static android.graphics.Typeface.Builder obtain();
- method public void recycle();
- method public void reset();
method public android.graphics.Typeface.Builder setFontVariationSettings(java.lang.String) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
method public android.graphics.Typeface.Builder setFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
- method public android.graphics.Typeface.Builder setItalic(int);
- method public android.graphics.Typeface.Builder setSourceFromAsset(android.content.res.AssetManager, java.lang.String);
- method public android.graphics.Typeface.Builder setSourceFromFile(java.io.File);
- method public android.graphics.Typeface.Builder setSourceFromFile(java.io.FileDescriptor);
- method public android.graphics.Typeface.Builder setSourceFromFilePath(java.lang.String);
+ method public android.graphics.Typeface.Builder setItalic(boolean);
method public android.graphics.Typeface.Builder setTtcIndex(int);
method public android.graphics.Typeface.Builder setWeight(int);
- field public static final int ITALIC = 1; // 0x1
- field public static final int NORMAL = 0; // 0x0
- field public static final int RESOLVE_BY_FONT_TABLE = -1; // 0xffffffff
}
public static abstract interface Typeface.FontRequestCallback {
@@ -14021,6 +14030,7 @@
method public boolean getPadding(android.graphics.Rect);
method public int[] getState();
method public android.graphics.Region getTransparentRegion();
+ method public boolean hasFocusStateSpecified();
method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void invalidateSelf();
@@ -14435,15 +14445,12 @@
field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontRequest> CREATOR;
}
- public final class FontVariationAxis implements android.os.Parcelable {
+ public final class FontVariationAxis {
ctor public FontVariationAxis(java.lang.String, float) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
- method public int describeContents();
method public static android.graphics.fonts.FontVariationAxis[] fromFontVariationSettings(java.lang.String) throws android.graphics.fonts.FontVariationAxis.InvalidFormatException;
method public float getStyleValue();
method public java.lang.String getTag();
method public static java.lang.String toFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontVariationAxis> CREATOR;
}
public static class FontVariationAxis.InvalidFormatException extends java.lang.Exception {
@@ -21918,24 +21925,19 @@
field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
}
- public final class MediaCas {
+ public final class MediaCas implements java.lang.AutoCloseable {
ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
- method public void closeSession(byte[]);
+ method public void close();
method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
method public static boolean isSystemIdSupported(int);
- method public byte[] openSession(int) throws android.media.MediaCasException;
- method public byte[] openSession(int, int) throws android.media.MediaCasException;
- method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
- method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
+ method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
method public void processEmm(byte[]) throws android.media.MediaCasException;
method public void provision(java.lang.String) throws android.media.MediaCasException;
method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
- method public void release();
method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
method public void setPrivateData(byte[]) throws android.media.MediaCasException;
- method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
}
public static abstract interface MediaCas.EventListener {
@@ -21947,6 +21949,13 @@
method public int getSystemId();
}
+ public final class MediaCas.Session implements java.lang.AutoCloseable {
+ method public void close();
+ method public void processEcm(byte[], int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[]) throws android.media.MediaCasException;
+ method public void setPrivateData(byte[]) throws android.media.MediaCasException;
+ }
+
public class MediaCasException extends java.lang.Exception {
}
@@ -22390,12 +22399,12 @@
method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
}
- public final class MediaDescrambler {
+ public final class MediaDescrambler implements java.lang.AutoCloseable {
ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
- method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
- method public final void release();
+ method public void close();
+ method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
method public final boolean requiresSecureDecoderComponent(java.lang.String);
- method public final void setMediaCasSession(byte[]);
+ method public final void setMediaCasSession(android.media.MediaCas.Session);
}
public class MediaDescription implements android.os.Parcelable {
@@ -22533,6 +22542,7 @@
ctor public MediaExtractor();
method public boolean advance();
method public long getCachedDuration();
+ method public android.media.MediaExtractor.CasInfo getCasInfo(int);
method public android.media.DrmInitData getDrmInitData();
method public android.media.MediaMetricsSet getMetrics();
method public java.util.Map<java.util.UUID, byte[]> getPsshInfo();
@@ -22564,6 +22574,11 @@
field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
}
+ public static final class MediaExtractor.CasInfo {
+ method public android.media.MediaCas.Session getSession();
+ method public int getSystemId();
+ }
+
public final class MediaFormat {
ctor public MediaFormat();
method public final boolean containsKey(java.lang.String);
@@ -23732,7 +23747,7 @@
public static final class VolumeShaper.Configuration implements android.os.Parcelable {
method public int describeContents();
- method public double getDurationMs();
+ method public double getDurationMillis();
method public int getInterpolatorType();
method public static int getMaximumCurvePoints();
method public float[] getTimes();
@@ -23758,7 +23773,7 @@
method public android.media.VolumeShaper.Configuration.Builder scaleToEndVolume(float);
method public android.media.VolumeShaper.Configuration.Builder scaleToStartVolume(float);
method public android.media.VolumeShaper.Configuration.Builder setCurve(float[], float[]);
- method public android.media.VolumeShaper.Configuration.Builder setDurationMs(double);
+ method public android.media.VolumeShaper.Configuration.Builder setDurationMillis(double);
method public android.media.VolumeShaper.Configuration.Builder setInterpolatorType(int);
}
@@ -24817,6 +24832,8 @@
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+ field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+ field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
@@ -24831,6 +24848,9 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
+ field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+ field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+ field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
}
public static final class TvContract.Programs.Genres {
@@ -24877,6 +24897,8 @@
field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+ field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+ field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
@@ -24890,6 +24912,9 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
field public static final android.net.Uri CONTENT_URI;
+ field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+ field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+ field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
}
public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
@@ -34619,10 +34644,14 @@
}
public class FontsContract {
+ method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String);
+ method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]);
+ method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
}
public static final class FontsContract.Columns implements android.provider.BaseColumns {
ctor public FontsContract.Columns();
+ field public static final java.lang.String FILE_ID = "file_id";
field public static final java.lang.String ITALIC = "font_italic";
field public static final java.lang.String RESULT_CODE = "result_code";
field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
@@ -34634,6 +34663,23 @@
field public static final java.lang.String WEIGHT = "font_weight";
}
+ public static class FontsContract.FontFamilyResult {
+ method public android.provider.FontsContract.FontInfo[] getFonts();
+ method public int getStatusCode();
+ field public static final int STATUS_OK = 0; // 0x0
+ field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
+ field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
+ }
+
+ public static class FontsContract.FontInfo {
+ method public android.graphics.fonts.FontVariationAxis[] getAxes();
+ method public int getResultCode();
+ method public int getTtcIndex();
+ method public android.net.Uri getUri();
+ method public int getWeight();
+ method public boolean isItalic();
+ }
+
public final deprecated class LiveFolders implements android.provider.BaseColumns {
field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER";
field public static final java.lang.String DESCRIPTION = "description";
@@ -40305,7 +40351,8 @@
method public boolean hasIccCard();
method public boolean iccCloseLogicalChannel(int);
method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
- method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
+ method public deprecated android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
+ method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String, int);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
method public boolean isConcurrentVoiceAndDataSupported();
@@ -42820,7 +42867,7 @@
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;
@@ -45698,6 +45745,7 @@
method public java.lang.CharSequence getContentDescription();
method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
+ method public final boolean getDefaultFocusHighlightEnabled();
method public static int getDefaultSize(int, int);
method public android.view.Display getDisplay();
method public final int[] getDrawableState();
@@ -46020,6 +46068,7 @@
method public void setClipToOutline(boolean);
method public void setContentDescription(java.lang.CharSequence);
method public void setContextClickable(boolean);
+ method public void setDefaultFocusHighlightEnabled(boolean);
method public void setDrawingCacheBackgroundColor(int);
method public void setDrawingCacheEnabled(boolean);
method public void setDrawingCacheQuality(int);
@@ -49269,7 +49318,7 @@
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);
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index bfcad1b..1bcfb22 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -580,6 +580,11 @@
}
}
+ /**
+ * Wait until either {@link #restoreFinished} or {@link #restoreStarting} is called.
+ * Once one is called, it clears the internal flag again, so that the same observer intance
+ * can be reused for a next operation.
+ */
public void waitForCompletion() {
// The restoreFinished() callback will throw the 'done' flag; we
// just sit and wait on that notification.
@@ -590,6 +595,7 @@
} catch (InterruptedException ex) {
}
}
+ done = false;
}
}
}
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java
index ce114fd..345895b 100644
--- a/cmds/bu/src/com/android/commands/bu/Backup.java
+++ b/cmds/bu/src/com/android/commands/bu/Backup.java
@@ -57,7 +57,7 @@
} else if (arg.equals("restore")) {
doRestore(OsConstants.STDIN_FILENO);
} else {
- Log.e(TAG, "Invalid operation '" + arg + "'");
+ showUsage();
}
}
@@ -158,6 +158,21 @@
}
}
+ private static void showUsage() {
+ System.err.println(" backup [-f FILE] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all]");
+ System.err.println(" [-system|-nosystem] [-keyvalue|-nokeyvalue] [PACKAGE...]");
+ System.err.println(" write an archive of the device's data to FILE [default=backup.adb]");
+ System.err.println(" package list optional if -all/-shared are supplied");
+ System.err.println(" -apk/-noapk: do/don't back up .apk files (default -noapk)");
+ System.err.println(" -obb/-noobb: do/don't back up .obb files (default -noobb)");
+ System.err.println(" -shared|-noshared: do/don't back up shared storage (default -noshared)");
+ System.err.println(" -all: back up all installed applications");
+ System.err.println(" -system|-nosystem: include system apps in -all (default -system)");
+ System.err.println(" -keyvalue|-nokeyvalue: include apps that perform key/value backups.");
+ System.err.println(" (default -nokeyvalue)");
+ System.err.println(" restore FILE restore device contents from FILE");
+ }
+
private String nextArg() {
if (mNextArg >= mArgs.length) {
return null;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 06291ab..74822d1 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4521,12 +4521,20 @@
*/
public void startActivityForResultAsUser(Intent intent, int requestCode,
@Nullable Bundle options, UserHandle user) {
+ startActivityForResultAsUser(intent, mEmbeddedID, requestCode, options, user);
+ }
+
+ /**
+ * @hide Implement to provide correct calling token.
+ */
+ public void startActivityForResultAsUser(Intent intent, String resultWho, int requestCode,
+ @Nullable Bundle options, UserHandle user) {
if (mParent != null) {
throw new RuntimeException("Can't be called from a child");
}
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
- this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode,
+ this, mMainThread.getApplicationThread(), mToken, resultWho, intent, requestCode,
options, user);
if (ar != null) {
mMainThread.sendActivityResult(
@@ -4563,7 +4571,7 @@
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
- this, mMainThread.getApplicationThread(), mToken, this,
+ this, mMainThread.getApplicationThread(), mToken, mEmbeddedID,
intent, -1, options, user);
if (ar != null) {
mMainThread.sendActivityResult(
@@ -5092,6 +5100,15 @@
/**
* @hide
*/
+ public void startActivityAsUserFromFragment(@NonNull Fragment fragment,
+ @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options,
+ UserHandle user) {
+ startActivityForResultAsUser(intent, fragment.mWho, requestCode, options, user);
+ }
+
+ /**
+ * @hide
+ */
@Override
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
@@ -7463,6 +7480,14 @@
}
@Override
+ public void onStartActivityAsUserFromFragment(
+ Fragment fragment, Intent intent, int requestCode, Bundle options,
+ UserHandle user) {
+ Activity.this.startActivityAsUserFromFragment(
+ fragment, intent, requestCode, options, user);
+ }
+
+ @Override
public void onStartIntentSenderFromFragment(Fragment fragment, IntentSender intent,
int requestCode, @Nullable Intent fillInIntent, int flagsMask, int flagsValues,
int extraFlags, Bundle options) throws IntentSender.SendIntentException {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index aede1bb..80482ca 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -3387,6 +3387,26 @@
}
/**
+ * Return the importance of a given uid, based on the processes that are
+ * currently running. The return value is one of the importance constants defined
+ * in {@link RunningAppProcessInfo}, giving you the highest importance of all the
+ * processes that this uid has running. If there are no processes
+ * running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
+ * @hide
+ */
+ @SystemApi @TestApi
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ public int getUidImportance(int uid) {
+ try {
+ int procState = getService().getUidProcessState(uid,
+ mContext.getOpPackageName());
+ return RunningAppProcessInfo.procStateToImportance(procState);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Callback to get reports about changes to the importance of a uid. Use with
* {@link #addOnUidImportanceListener}.
* @hide
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index a3c123f..6487e67 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -34,6 +34,7 @@
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.transition.TransitionSet;
@@ -1188,6 +1189,19 @@
}
/**
+ * @hide
+ * Call {@link Activity#startActivityForResultAsUser(Intent, int, UserHandle)} from the
+ * fragment's containing Activity.
+ */
+ public void startActivityForResultAsUser(
+ Intent intent, int requestCode, Bundle options, UserHandle user) {
+ if (mHost == null) {
+ throw new IllegalStateException("Fragment " + this + " not attached to Activity");
+ }
+ mHost.onStartActivityAsUserFromFragment(this, intent, requestCode, options, user);
+ }
+
+ /**
* Call {@link Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int,
* Bundle)} from the fragment's containing Activity.
*/
diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index 41a885e..fb60e07 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -23,6 +23,7 @@
import android.content.IntentSender;
import android.os.Bundle;
import android.os.Handler;
+import android.os.UserHandle;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
@@ -146,6 +147,20 @@
}
/**
+ * @hide
+ * Starts a new {@link Activity} from the given fragment.
+ * See {@link Activity#startActivityForResult(Intent, int)}.
+ */
+ public void onStartActivityAsUserFromFragment(Fragment fragment, Intent intent, int requestCode,
+ Bundle options, UserHandle userHandle) {
+ if (requestCode != -1) {
+ throw new IllegalStateException(
+ "Starting activity with a requestCode requires a FragmentActivity host");
+ }
+ mContext.startActivityAsUser(intent, userHandle);
+ }
+
+ /**
* Starts a new {@link IntentSender} from the given fragment.
* See {@link Activity#startIntentSender(IntentSender, Intent, int, int, int, Bundle)}.
*/
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 079bbcd..595ad35 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -463,6 +463,7 @@
* etc.
*/
void keyguardGoingAway(int flags);
+ int getUidProcessState(int uid, in String callingPackage);
void registerUidObserver(in IUidObserver observer, int which, int cutpoint,
String callingPackage);
void unregisterUidObserver(in IUidObserver observer);
@@ -576,17 +577,6 @@
* @param hasTopUi Whether the calling process has "top-level" UI.
*/
void setHasTopUi(boolean hasTopUi);
- /**
- * Returns if the target of the PendingIntent can be fired directly, without triggering
- * a work profile challenge. This can happen if the PendingIntent is to start direct-boot
- * aware activities, and the target user is in RUNNING_LOCKED state, i.e. we should allow
- * direct-boot aware activity to bypass work challenge when the user hasn't unlocked yet.
- * @param intent the {@link PendingIntent} to be tested.
- * @return {@code true} if the intent should not trigger a work challenge, {@code false}
- * otherwise.
- * @throws RemoteException
- */
- boolean canBypassWorkChallenge(in PendingIntent intent);
// Start of O transactions
void requestActivityRelaunch(in IBinder token);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index d546f27..9377d35 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1779,7 +1779,7 @@
* {@hide}
*/
public ActivityResult execStartActivity(
- Context who, IBinder contextThread, IBinder token, Activity target,
+ Context who, IBinder contextThread, IBinder token, String resultWho,
Intent intent, int requestCode, Bundle options, UserHandle user) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
@@ -1810,7 +1810,7 @@
int result = ActivityManager.getService()
.startActivityAsUser(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target != null ? target.mEmbeddedID : null,
+ token, resultWho,
requestCode, 0, null, options, user.getIdentifier());
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
diff --git a/core/java/android/app/JobSchedulerImpl.java b/core/java/android/app/JobSchedulerImpl.java
index e30b96f..4ac44f7 100644
--- a/core/java/android/app/JobSchedulerImpl.java
+++ b/core/java/android/app/JobSchedulerImpl.java
@@ -20,6 +20,8 @@
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.IJobScheduler;
+import android.app.job.JobWorkItem;
+import android.content.Intent;
import android.os.RemoteException;
import java.util.List;
@@ -46,6 +48,15 @@
}
@Override
+ public int enqueue(JobInfo job, JobWorkItem work) {
+ try {
+ return mBinder.enqueue(job, work);
+ } catch (RemoteException e) {
+ return JobScheduler.RESULT_FAILURE;
+ }
+ }
+
+ @Override
public int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag) {
try {
return mBinder.scheduleAsPackage(job, packageName, userId, tag);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 4572578..19f7426 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -641,7 +641,8 @@
new CachedServiceFetcher<PrintManager>() {
@Override
public PrintManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder iBinder = ServiceManager.getServiceOrThrow(Context.PRINT_SERVICE);
+ // Get the services without throwing as this is an optional feature
+ IBinder iBinder = ServiceManager.getService(Context.PRINT_SERVICE);
IPrintManager service = IPrintManager.Stub.asInterface(iBinder);
return new PrintManager(ctx.getOuterContext(), service, UserHandle.myUserId(),
UserHandle.getAppId(Process.myUid()));
@@ -652,8 +653,9 @@
@Override
public CompanionDeviceManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
+ // Get the services without throwing as this is an optional feature
IBinder iBinder =
- ServiceManager.getServiceOrThrow(Context.COMPANION_DEVICE_SERVICE);
+ ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE);
ICompanionDeviceManager service =
ICompanionDeviceManager.Stub.asInterface(iBinder);
return new CompanionDeviceManager(service, ctx);
@@ -833,7 +835,8 @@
new CachedServiceFetcher<AutofillManager>() {
@Override
public AutofillManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.AUTOFILL_MANAGER_SERVICE);
+ // Get the services without throwing as this is an optional feature
+ IBinder b = ServiceManager.getService(Context.AUTOFILL_MANAGER_SERVICE);
IAutoFillManager service = IAutoFillManager.Stub.asInterface(b);
return new AutofillManager(ctx.getOuterContext(), service);
}});
diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java
index 790a952..2b590e0 100644
--- a/core/java/android/app/admin/SecurityLog.java
+++ b/core/java/android/app/admin/SecurityLog.java
@@ -27,6 +27,16 @@
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
+/**
+ * Definitions for working with security logs.
+ *
+ * <p>Device owner apps can control the logging with
+ * {@link DevicePolicyManager#setSecurityLoggingEnabled}. When security logs are enabled, device
+ * owner apps receive periodic callbacks from {@link DeviceAdminReceiver#onSecurityLogsAvailable},
+ * at which time new batch of logs can be collected via
+ * {@link DevicePolicyManager#retrieveSecurityLogs}. {@link SecurityEvent} describes the type and
+ * format of security logs being collected.
+ */
public class SecurityLog {
private static final String PROPERTY_LOGGING_ENABLED = "persist.logd.security";
diff --git a/core/java/android/app/job/IJobCallback.aidl b/core/java/android/app/job/IJobCallback.aidl
index 2d3948f..e7695e2e 100644
--- a/core/java/android/app/job/IJobCallback.aidl
+++ b/core/java/android/app/job/IJobCallback.aidl
@@ -16,6 +16,8 @@
package android.app.job;
+import android.app.job.JobWorkItem;
+
/**
* The server side of the JobScheduler IPC protocols. The app-side implementation
* invokes on this interface to indicate completion of the (asynchronous) instructions
@@ -43,6 +45,14 @@
*/
void acknowledgeStopMessage(int jobId, boolean reschedule);
/*
+ * Called to deqeue next work item for the job.
+ */
+ JobWorkItem dequeueWork(int jobId);
+ /*
+ * Called to report that job has completed processing a work item.
+ */
+ boolean completeWork(int jobId, int workId);
+ /*
* Tell the job manager that the client is done with its execution, so that it can go on to
* the next one and stop attributing wakelock time to us etc.
*
diff --git a/core/java/android/app/job/IJobScheduler.aidl b/core/java/android/app/job/IJobScheduler.aidl
index b6eec27..e94da0c 100644
--- a/core/java/android/app/job/IJobScheduler.aidl
+++ b/core/java/android/app/job/IJobScheduler.aidl
@@ -17,6 +17,7 @@
package android.app.job;
import android.app.job.JobInfo;
+import android.app.job.JobWorkItem;
/**
* IPC interface that supports the app-facing {@link #JobScheduler} api.
@@ -24,6 +25,7 @@
*/
interface IJobScheduler {
int schedule(in JobInfo job);
+ int enqueue(in JobInfo job, in JobWorkItem work);
int scheduleAsPackage(in JobInfo job, String packageName, int userId, String tag);
void cancel(int jobId);
void cancelAll();
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 8220ff9..412e445 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -23,6 +23,7 @@
import android.content.ClipData;
import android.content.ComponentName;
import android.net.Uri;
+import android.os.BaseBundle;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -442,6 +443,130 @@
return hasLateConstraint;
}
+ private static boolean kindofEqualsBundle(BaseBundle a, BaseBundle b) {
+ return (a == b) || (a != null && a.kindofEquals(b));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof JobInfo)) {
+ return false;
+ }
+ JobInfo j = (JobInfo) o;
+ if (jobId != j.jobId) {
+ return false;
+ }
+ // XXX won't be correct if one is parcelled and the other not.
+ if (!kindofEqualsBundle(extras, j.extras)) {
+ return false;
+ }
+ // XXX won't be correct if one is parcelled and the other not.
+ if (!kindofEqualsBundle(transientExtras, j.transientExtras)) {
+ return false;
+ }
+ // XXX for now we consider two different clip data objects to be different,
+ // regardless of whether their contents are the same.
+ if (clipData != j.clipData) {
+ return false;
+ }
+ if (clipGrantFlags != j.clipGrantFlags) {
+ return false;
+ }
+ if (!Objects.equals(service, j.service)) {
+ return false;
+ }
+ if (constraintFlags != j.constraintFlags) {
+ return false;
+ }
+ if (!Objects.deepEquals(triggerContentUris, j.triggerContentUris)) {
+ return false;
+ }
+ if (triggerContentUpdateDelay != j.triggerContentUpdateDelay) {
+ return false;
+ }
+ if (triggerContentMaxDelay != j.triggerContentMaxDelay) {
+ return false;
+ }
+ if (hasEarlyConstraint != j.hasEarlyConstraint) {
+ return false;
+ }
+ if (hasLateConstraint != j.hasLateConstraint) {
+ return false;
+ }
+ if (networkType != j.networkType) {
+ return false;
+ }
+ if (minLatencyMillis != j.minLatencyMillis) {
+ return false;
+ }
+ if (maxExecutionDelayMillis != j.maxExecutionDelayMillis) {
+ return false;
+ }
+ if (isPeriodic != j.isPeriodic) {
+ return false;
+ }
+ if (isPersisted != j.isPersisted) {
+ return false;
+ }
+ if (intervalMillis != j.intervalMillis) {
+ return false;
+ }
+ if (flexMillis != j.flexMillis) {
+ return false;
+ }
+ if (initialBackoffMillis != j.initialBackoffMillis) {
+ return false;
+ }
+ if (backoffPolicy != j.backoffPolicy) {
+ return false;
+ }
+ if (priority != j.priority) {
+ return false;
+ }
+ if (flags != j.flags) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = jobId;
+ if (extras != null) {
+ hashCode = 31*hashCode + extras.hashCode();
+ }
+ if (transientExtras != null) {
+ hashCode = 31*hashCode + transientExtras.hashCode();
+ }
+ if (clipData != null) {
+ hashCode = 31*hashCode + clipData.hashCode();
+ }
+ hashCode = 31*hashCode + clipGrantFlags;
+ if (service != null) {
+ hashCode = 31*hashCode + service.hashCode();
+ }
+ hashCode = 31*hashCode + constraintFlags;
+ if (triggerContentUris != null) {
+ hashCode = 31*hashCode + triggerContentUris.hashCode();
+ }
+ hashCode = 31*hashCode + Long.hashCode(triggerContentUpdateDelay);
+ hashCode = 31*hashCode + Long.hashCode(triggerContentMaxDelay);
+ hashCode = 31*hashCode + Boolean.hashCode(hasEarlyConstraint);
+ hashCode = 31*hashCode + Boolean.hashCode(hasLateConstraint);
+ hashCode = 31*hashCode + networkType;
+ hashCode = 31*hashCode + Long.hashCode(minLatencyMillis);
+ hashCode = 31*hashCode + Long.hashCode(maxExecutionDelayMillis);
+ hashCode = 31*hashCode + Boolean.hashCode(isPeriodic);
+ hashCode = 31*hashCode + Boolean.hashCode(isPersisted);
+ hashCode = 31*hashCode + Long.hashCode(intervalMillis);
+ hashCode = 31*hashCode + Long.hashCode(flexMillis);
+ hashCode = 31*hashCode + Long.hashCode(initialBackoffMillis);
+ hashCode = 31*hashCode + backoffPolicy;
+ hashCode = 31*hashCode + priority;
+ hashCode = 31*hashCode + flags;
+ return hashCode;
+ }
+
private JobInfo(Parcel in) {
jobId = in.readInt();
extras = in.readPersistableBundle();
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index 8d52d3b..016a0fa 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -24,6 +24,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
+import android.os.RemoteException;
/**
* Contains the parameters used to configure/identify your job. You do not create this object
@@ -155,6 +156,53 @@
return mTriggeredContentAuthorities;
}
+ /**
+ * Dequeue the next pending {@link JobWorkItem} from these JobParameters associated with their
+ * currently running job. Calling this method when there is no more work available and all
+ * previously dequeued work has been completed will result in the system taking care of
+ * stopping the job for you --
+ * you should not call {@link JobService#jobFinished(JobParameters, boolean)} yourself
+ * (otherwise you risk losing an upcoming JobWorkItem that is being enqueued at the same time).
+ *
+ * @return Returns a new {@link JobWorkItem} if there is one pending, otherwise null.
+ * If null is returned, the system will also stop the job if all work has also been completed.
+ * (This means that for correct operation, you must always call dequeueWork() after you have
+ * completed other work, to check either for more work or allow the system to stop the job.)
+ */
+ public JobWorkItem dequeueWork() {
+ try {
+ return getCallback().dequeueWork(getJobId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Report the completion of executing a {@link JobWorkItem} previously returned by
+ * {@link #dequeueWork()}. This tells the system you are done with the
+ * work associated with that item, so it will not be returned again. Note that if this
+ * is the last work in the queue, completing it here will <em>not</em> finish the overall
+ * job -- for that to happen, you still need to call {@link #dequeueWork()}
+ * again.
+ *
+ * <p>If you are enqueueing work into a job, you must call this method for each piece
+ * of work you process. Do <em>not</em> call
+ * {@link JobService#jobFinished(JobParameters, boolean)}
+ * or else you can lose work in your queue.</p>
+ *
+ * @param work The work you have completed processing, as previously returned by
+ * {@link #dequeueWork()}
+ */
+ public void completeWork(JobWorkItem work) {
+ try {
+ if (!getCallback().completeWork(getJobId(), work.getWorkId())) {
+ throw new IllegalArgumentException("Given work is not active: " + work);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/** @hide */
public IJobCallback getCallback() {
return IJobCallback.Stub.asInterface(callback);
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
index 1b640d0..e0afe03 100644
--- a/core/java/android/app/job/JobScheduler.java
+++ b/core/java/android/app/job/JobScheduler.java
@@ -19,6 +19,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.content.ClipData;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.PersistableBundle;
import java.util.List;
@@ -59,6 +63,10 @@
public static final int RESULT_SUCCESS = 1;
/**
+ * Schedule a job to be executed. Will replace any currently scheduled job with the same
+ * ID with the new information in the {@link JobInfo}. If a job with the given ID is currently
+ * running, it will be stopped.
+ *
* @param job The job you wish scheduled. See
* {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
* you can schedule.
@@ -67,6 +75,42 @@
public abstract int schedule(JobInfo job);
/**
+ * Similar to {@link #schedule}, but allows you to enqueue work for an existing job. If a job
+ * with the same ID is already scheduled, it will be replaced with the new {@link JobInfo}, but
+ * any previously enqueued work will remain and be dispatched the next time it runs. If a job
+ * with the same ID is already running, the new work will be enqueued for it.
+ *
+ * <p>The work you enqueue is later retrieved through
+ * {@link JobParameters#dequeueWork() JobParameters.dequeueWork()}. Be sure to see there
+ * about how to process work; the act of enqueueing work changes how you should handle the
+ * overall lifecycle of an executing job.</p>
+ *
+ * <p>It is strongly encouraged that you use the same {@link JobInfo} for all work you
+ * enqueue. This will allow the system to optimal schedule work along with any pending
+ * and/or currently running work. If the JobInfo changes from the last time the job was
+ * enqueued, the system will need to update the associated JobInfo, which can cause a disruption
+ * in exection. In particular, this can result in any currently running job that is processing
+ * previous work to be stopped and restarted with the new JobInfo.</p>
+ *
+ * <p>It is recommended that you avoid using
+ * {@link JobInfo.Builder#setExtras(PersistableBundle)} or
+ * {@link JobInfo.Builder#setTransientExtras(Bundle)} with a JobInfo you are using to
+ * enqueue work. The system will try to compare these extras with the previous JobInfo,
+ * but there are situations where it may get this wrong and count the JobInfo as changing.
+ * (That said, you should be relatively safe with a simple set of consistent data in these
+ * fields.) You should never use {@link JobInfo.Builder#setClipData(ClipData, int)} with
+ * work you are enqueue, since currently this will always be treated as a different JobInfo,
+ * even if the ClipData contents is exactly the same.</p>
+ *
+ * @param job The job you wish to enqueue work for. See
+ * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
+ * you can schedule.
+ * @param work New work to enqueue. This will be available later when the job starts running.
+ * @return An int representing ({@link #RESULT_SUCCESS} or {@link #RESULT_FAILURE}).
+ */
+ public abstract int enqueue(JobInfo job, JobWorkItem work);
+
+ /**
*
* @param job The job to be scheduled.
* @param packageName The package on behalf of which the job is to be scheduled. This will be
diff --git a/core/java/android/app/job/JobWorkItem.aidl b/core/java/android/app/job/JobWorkItem.aidl
new file mode 100644
index 0000000..e8fe47d
--- /dev/null
+++ b/core/java/android/app/job/JobWorkItem.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.job;
+
+/** @hide */
+parcelable JobWorkItem;
diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java
new file mode 100644
index 0000000..4bb057e
--- /dev/null
+++ b/core/java/android/app/job/JobWorkItem.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.job;
+
+import android.content.Intent;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A unit of work that can be enqueued for a job using
+ * {@link JobScheduler#enqueue JobScheduler.enqueue}.
+ */
+final public class JobWorkItem implements Parcelable {
+ final Intent mIntent;
+ int mWorkId;
+
+ /**
+ * Create a new piece of work.
+ * @param intent The general Intent describing this work.
+ */
+ public JobWorkItem(Intent intent) {
+ mIntent = intent;
+ }
+
+ /**
+ * Return the Intent associated with this work.
+ */
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ /**
+ * @hide
+ */
+ public void setWorkId(int id) {
+ mWorkId = id;
+ }
+
+ /**
+ * @hide
+ */
+ public int getWorkId() {
+ return mWorkId;
+ }
+
+ public String toString() {
+ return "JobWorkItem{id=" + mWorkId + " intent=" + mIntent + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ if (mIntent != null) {
+ out.writeInt(1);
+ mIntent.writeToParcel(out, 0);
+ } else {
+ out.writeInt(0);
+ }
+ out.writeInt(mWorkId);
+ }
+
+ public static final Parcelable.Creator<JobWorkItem> CREATOR
+ = new Parcelable.Creator<JobWorkItem>() {
+ public JobWorkItem createFromParcel(Parcel in) {
+ return new JobWorkItem(in);
+ }
+
+ public JobWorkItem[] newArray(int size) {
+ return new JobWorkItem[size];
+ }
+ };
+
+ public JobWorkItem(Parcel in) {
+ if (in.readInt() != 0) {
+ mIntent = Intent.CREATOR.createFromParcel(in);
+ } else {
+ mIntent = null;
+ }
+ mWorkId = in.readInt();
+ }
+}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b382cef..a4b5ffd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1437,6 +1437,20 @@
public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY";
/**
+ * Activity Action: Setup wizard action provided for OTA provisioning to determine if it needs
+ * to run.
+ * <p>Input: Nothing.
+ * <p>Output: Nothing.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, setup wizard can be identified
+ * using {@link #ACTION_MAIN} and {@link #CATEGORY_SETUP_WIZARD}
+ * @hide
+ */
+ @Deprecated
+ @SystemApi
+ public static final String ACTION_DEVICE_INITIALIZATION_WIZARD =
+ "android.intent.action.DEVICE_INITIALIZATION_WIZARD";
+
+ /**
* Activity Action: Setup wizard to launch after a platform update. This
* activity should have a string meta-data field associated with it,
* {@link #METADATA_SETUP_VERSION}, which defines the current version of
@@ -1447,6 +1461,7 @@
* <p>Output: Nothing.
* @hide
*/
+ @SystemApi
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP";
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4bd44c1..c7a0da5 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2404,6 +2404,15 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+ * The device supports autofill of user credentials, addresses, credit cards, etc
+ * via integration with {@link android.service.autofill.AutofillService autofill
+ * providers}.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_AUTOFILL = "android.software.autofill";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
* The device implements headtracking suitable for a VR device.
*/
@SdkConstant(SdkConstantType.FEATURE)
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index a46db06..faf2381 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -91,7 +91,7 @@
* file. An item with no state spec is considered to match any set of states and is generally
* useful as a final item to be used as a default.
* <p>
- * If an item with no state spec if placed before other items, those items
+ * If an item with no state spec is placed before other items, those items
* will be ignored.
*
* <a name="ItemAttributes"></a>
@@ -521,6 +521,15 @@
}
/**
+ * Return whether the state spec list has at least one item explicitly specifying
+ * {@link android.R.attr#state_focused}.
+ * @hide
+ */
+ public boolean hasFocusStateSpecified() {
+ return StateSet.containsAttribute(mStateSpecs, R.attr.state_focused);
+ }
+
+ /**
* Indicates whether this color state list is opaque, which means that every
* color returned from {@link #getColorForState(int[], int)} has an alpha
* value of 255.
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 6f388e2..65025fb 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -325,6 +325,23 @@
}
/**
+ * @hide This kind-of does an equality comparison. Kind-of.
+ */
+ public boolean kindofEquals(BaseBundle other) {
+ if (other == null) {
+ return false;
+ }
+ if (isParcelled() != other.isParcelled()) {
+ // Big kind-of here!
+ return false;
+ } else if (isParcelled()) {
+ return mParcelledData.compareData(other.mParcelledData) == 0;
+ } else {
+ return mMap.equals(other.mMap);
+ }
+ }
+
+ /**
* Removes all elements from the mapping of this Bundle.
*/
public void clear() {
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 76128e6..c3836a3 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -315,6 +315,7 @@
private static native byte[] nativeMarshall(long nativePtr);
private static native long nativeUnmarshall(
long nativePtr, byte[] data, int offset, int length);
+ private static native int nativeCompareData(long thisNativePtr, long otherNativePtr);
private static native long nativeAppendFrom(
long thisNativePtr, long otherNativePtr, int offset, int length);
@FastNative
@@ -487,6 +488,11 @@
updateNativeSize(nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length));
}
+ /** @hide */
+ public final int compareData(Parcel other) {
+ return nativeCompareData(mNativePtr, other.mNativePtr);
+ }
+
/**
* Report whether the parcel contains any marshalled file descriptors.
*/
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index b1f6421..c6bbf48 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -19,6 +19,7 @@
import android.app.ActivityThread;
import android.content.Context;
import android.media.AudioAttributes;
+import android.util.Log;
/**
* Class that operates the vibrator on the device.
@@ -30,6 +31,7 @@
* {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as the argument.
*/
public abstract class Vibrator {
+ private static final String TAG = "Vibrator";
private final String mPackageName;
@@ -90,9 +92,14 @@
*/
@Deprecated
public void vibrate(long milliseconds, AudioAttributes attributes) {
- VibrationEffect effect =
- VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE);
- vibrate(effect, attributes);
+ try {
+ // This ignores all exceptions to stay compatible with pre-O implementations.
+ VibrationEffect effect =
+ VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE);
+ vibrate(effect, attributes);
+ } catch (IllegalArgumentException iae) {
+ Log.e(TAG, "Failed to create VibrationEffect", iae);
+ }
}
/**
@@ -150,12 +157,17 @@
*/
@Deprecated
public void vibrate(long[] pattern, int repeat, AudioAttributes attributes) {
- // This call needs to continue throwing ArrayIndexOutOfBoundsException for compatibility
- // purposes, whereas VibrationEffect throws an IllegalArgumentException.
+ // This call needs to continue throwing ArrayIndexOutOfBoundsException but ignore all other
+ // exceptions for compatibility purposes
if (repeat < -1 || repeat >= pattern.length) {
throw new ArrayIndexOutOfBoundsException();
}
- vibrate(VibrationEffect.createWaveform(pattern, repeat), attributes);
+
+ try {
+ vibrate(VibrationEffect.createWaveform(pattern, repeat), attributes);
+ } catch (IllegalArgumentException iae) {
+ Log.e(TAG, "Failed to create VibrationEffect", iae);
+ }
}
public void vibrate(VibrationEffect vibe) {
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index 4deb4ab..f9508902 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -15,10 +15,18 @@
*/
package android.provider;
+import static android.graphics.fonts.FontVariationAxis.InvalidFormatException;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.Signature;
@@ -26,8 +34,10 @@
import android.graphics.Typeface;
import android.graphics.fonts.FontRequest;
import android.graphics.fonts.FontResult;
+import android.graphics.fonts.FontVariationAxis;
import android.net.Uri;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
@@ -37,14 +47,22 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Utility class to deal with Font ContentProviders.
@@ -62,6 +80,15 @@
public static final class Columns implements BaseColumns {
/**
* Constant used to request data from a font provider. The cursor returned from the query
+ * may populate this column with a long for the font file ID. The client will request a file
+ * descriptor to "file/FILE_ID" with this ID immediately under the top-level content URI. If
+ * not present, the client will request a file descriptor to the top-level URI with the
+ * given base font ID. Note that several results may return the same file ID, e.g. for TTC
+ * files with different indices.
+ */
+ public static final String FILE_ID = "file_id";
+ /**
+ * Constant used to request data from a font provider. The cursor returned from the query
* should have this column populated with an int for the ttc index for the resulting font.
*/
public static final String TTC_INDEX = "font_ttc_index";
@@ -131,7 +158,6 @@
* @hide
*/
public static final String PARCEL_FONT_RESULTS = "font_results";
-
// Error codes internal to the system, which can not come from a provider. To keep the number
// space open for new provider codes, these should all be negative numbers.
/** @hide */
@@ -156,11 +182,128 @@
mPackageManager = mContext.getPackageManager();
}
- /** @hide */
- @VisibleForTesting
- public FontsContract(Context context, PackageManager packageManager) {
- mContext = context;
- mPackageManager = packageManager;
+ /**
+ * Object represent a font entry in the family returned from {@link #fetchFonts}.
+ */
+ public static class FontInfo {
+ private final Uri mUri;
+ private final int mTtcIndex;
+ private final FontVariationAxis[] mAxes;
+ private final int mWeight;
+ private final boolean mItalic;
+ private final int mResultCode;
+
+ /**
+ * Creates a Font with all the information needed about a provided font.
+ * @param uri A URI associated to the font file.
+ * @param ttcIndex If providing a TTC_INDEX file, the index to point to. Otherwise, 0.
+ * @param axes If providing a variation font, the settings for it. May be null.
+ * @param weight An integer that indicates the font weight.
+ * @param italic A boolean that indicates the font is italic style or not.
+ * @param resultCode A boolean that indicates the font contents is ready.
+ */
+ /** @hide */
+ public FontInfo(@NonNull Uri uri, @IntRange(from = 0) int ttcIndex,
+ @Nullable FontVariationAxis[] axes, @IntRange(from = 1, to = 1000) int weight,
+ boolean italic, int resultCode) {
+ mUri = Preconditions.checkNotNull(uri);
+ mTtcIndex = ttcIndex;
+ mAxes = axes;
+ mWeight = weight;
+ mItalic = italic;
+ mResultCode = resultCode;
+ }
+
+ /**
+ * Returns a URI associated to this record.
+ */
+ public @NonNull Uri getUri() {
+ return mUri;
+ }
+
+ /**
+ * Returns the index to be used to access this font when accessing a TTC file.
+ */
+ public @IntRange(from = 0) int getTtcIndex() {
+ return mTtcIndex;
+ }
+
+ /**
+ * Returns the list of axes associated to this font.
+ */
+ public @Nullable FontVariationAxis[] getAxes() {
+ return mAxes;
+ }
+
+ /**
+ * Returns the weight value for this font.
+ */
+ public @IntRange(from = 1, to = 1000) int getWeight() {
+ return mWeight;
+ }
+
+ /**
+ * Returns whether this font is italic.
+ */
+ public boolean isItalic() {
+ return mItalic;
+ }
+
+ /**
+ * Returns result code.
+ *
+ * {@link FontsContract.Columns#RESULT_CODE}
+ */
+ public int getResultCode() {
+ return mResultCode;
+ }
+ }
+
+ /**
+ * Object returned from {@link #fetchFonts}.
+ */
+ public static class FontFamilyResult {
+ /**
+ * Constant represents that the font was successfully retrieved. Note that when this value
+ * is set and {@link #getFonts} returns an empty array, it means there were no fonts
+ * matching the given query.
+ */
+ public static final int STATUS_OK = 0;
+
+ /**
+ * Constant represents that the given certificate was not matched with the provider's
+ * signature. {@link #getFonts} returns null if this status was set.
+ */
+ public static final int STATUS_WRONG_CERTIFICATES = 1;
+
+ /**
+ * Constant represents that the provider returns unexpected data. {@link #getFonts} returns
+ * null if this status was set. For example, this value is set when the font provider
+ * gives invalid format of variation settings.
+ */
+ public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2;
+
+ /** @hide */
+ @IntDef({STATUS_OK, STATUS_WRONG_CERTIFICATES, STATUS_UNEXPECTED_DATA_PROVIDED})
+ @Retention(RetentionPolicy.SOURCE)
+ @interface FontResultStatus {}
+
+ private final @FontResultStatus int mStatusCode;
+ private final FontInfo[] mFonts;
+
+ /** @hide */
+ public FontFamilyResult(@FontResultStatus int statusCode, @Nullable FontInfo[] fonts) {
+ mStatusCode = statusCode;
+ mFonts = fonts;
+ }
+
+ public @FontResultStatus int getStatusCode() {
+ return mStatusCode;
+ }
+
+ public @NonNull FontInfo[] getFonts() {
+ return mFonts;
+ }
}
// We use a background thread to post the content resolving work for all requests on. This
@@ -187,33 +330,210 @@
mHandler = new Handler(mThread.getLooper());
}
mHandler.post(() -> {
- ProviderInfo providerInfo = getProvider(request, receiver);
- if (providerInfo == null) {
+ ProviderInfo providerInfo;
+ try {
+ providerInfo = getProvider(mPackageManager, request);
+ if (providerInfo == null) {
+ receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
+ return;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
return;
}
- getFontFromProvider(request, receiver, providerInfo.authority);
+ FontInfo[] fonts;
+ try {
+ fonts = getFontFromProvider(mContext, request, providerInfo.authority,
+ null /* cancellation signal */);
+ } catch (InvalidFormatException e) {
+ receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
+ return;
+ }
+
+ ArrayList<FontResult> result = new ArrayList<>();
+ int resultCode = -1;
+ for (FontInfo font : fonts) {
+ try {
+ resultCode = font.getResultCode();
+ if (resultCode != Columns.RESULT_CODE_OK) {
+ if (resultCode < 0) {
+ // Negative values are reserved for the internal errors.
+ resultCode = Columns.RESULT_CODE_FONT_NOT_FOUND;
+ }
+ for (int i = 0; i < result.size(); ++i) {
+ try {
+ result.get(i).getFileDescriptor().close();
+ } catch (IOException e) {
+ // Ignore, as we are closing fds for cleanup.
+ }
+ }
+ receiver.send(resultCode, null);
+ return;
+ }
+ ParcelFileDescriptor pfd = mContext.getContentResolver().openFileDescriptor(
+ font.getUri(), "r");
+ result.add(new FontResult(pfd, font.getTtcIndex(),
+ FontVariationAxis.toFontVariationSettings(font.getAxes()),
+ font.getWeight(), font.isItalic()));
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "FileNotFoundException raised when interacting with content "
+ + "provider " + providerInfo.authority, e);
+ }
+ }
+ if (!result.isEmpty()) {
+ Bundle bundle = new Bundle();
+ bundle.putParcelableArrayList(PARCEL_FONT_RESULTS, result);
+ receiver.send(Columns.RESULT_CODE_OK, bundle);
+ return;
+ }
+ receiver.send(Columns.RESULT_CODE_FONT_NOT_FOUND, null);
});
mHandler.removeCallbacks(mReplaceDispatcherThreadRunnable);
mHandler.postDelayed(mReplaceDispatcherThreadRunnable, THREAD_RENEWAL_THRESHOLD_MS);
}
}
+ /**
+ * Fetch fonts given a font request.
+ *
+ * @param context A {@link Context} to be used for fetching fonts.
+ * @param cancellationSignal A signal to cancel the operation in progress, or null if none. If
+ * the operation is canceled, then {@link
+ * android.os.OperationCanceledException} will be thrown when the
+ * query is executed.
+ * @param request A {@link FontRequest} object that identifies the provider and query for the
+ * request.
+ *
+ * @return {@link FontFamilyResult}
+ *
+ * @throws NameNotFoundException If requested package or authority was not found in system.
+ */
+ public static @NonNull FontFamilyResult fetchFonts(
+ @NonNull Context context, @Nullable CancellationSignal cancellationSignal,
+ @NonNull FontRequest request) throws NameNotFoundException {
+ ProviderInfo providerInfo = getProvider(context.getPackageManager(), request);
+ if (providerInfo == null) {
+ return new FontFamilyResult(FontFamilyResult.STATUS_WRONG_CERTIFICATES, null);
+
+ }
+ try {
+ FontInfo[] fonts = getFontFromProvider(
+ context, request, providerInfo.authority, cancellationSignal);
+ return new FontFamilyResult(FontFamilyResult.STATUS_OK, fonts);
+ } catch (InvalidFormatException e) {
+ return new FontFamilyResult(FontFamilyResult.STATUS_UNEXPECTED_DATA_PROVIDED, null);
+ }
+ }
+
+ /**
+ * Build a Typeface from an array of {@link FontInfo}. Results that are marked as not ready
+ * will be skipped.
+ *
+ * @param context A {@link Context} that will be used to fetch the font contents.
+ * @param cancellationSignal A signal to cancel the operation in progress, or null if none. If
+ * the operation is canceled, then {@link
+ * android.os.OperationCanceledException} will be thrown.
+ * @param fonts An array of {@link FontInfo} to be used to create a Typeface.
+ * @param weight A weight value to be used for selecting a font from a font family.
+ * @param italic {@code true} if this font is of italic style. This will be used for font
+ * selection from a font family.
+ * @param fallbackFontName A fallback font name used if this method fails to create the
+ * Typeface. By passing {@code null}, this method returns {@code null}
+ * if typeface creation fails.
+ * @return A Typeface object. May return {@code null} if that is the value passed to {@code
+ * fallBackFontName}.
+ */
+ public static Typeface buildTypeface(@NonNull Context context,
+ @Nullable CancellationSignal cancellationSignal, @NonNull FontInfo[] fonts,
+ int weight, boolean italic, @Nullable String fallbackFontName) {
+ final Map<Uri, ByteBuffer> uriBuffer =
+ prepareFontData(context, fonts, cancellationSignal);
+ Typeface typeface = new Typeface.Builder(fonts, uriBuffer)
+ .setWeight(weight)
+ .setItalic(italic)
+ .build();
+ // TODO: Use Typeface fallback instead.
+ if (typeface == null) {
+ typeface = Typeface.create(fallbackFontName, Typeface.NORMAL);
+ }
+ return typeface;
+ }
+
+ /**
+ * Build a Typeface from an array of {@link FontInfo}
+ *
+ * Results that are marked as not ready will be skipped.
+ *
+ * @param context A {@link Context} that will be used to fetch the font contents.
+ * @param cancellationSignal A signal to cancel the operation in progress, or null if none. If
+ * the operation is canceled, then {@link
+ * android.os.OperationCanceledException} will be thrown.
+ * @param fonts An array of {@link FontInfo} to be used to create a Typeface.
+ * @return A Typeface object. Returns null if typeface creation fails.
+ */
+ public static Typeface buildTypeface(@NonNull Context context,
+ @Nullable CancellationSignal cancellationSignal, @NonNull FontInfo[] fonts) {
+ final Map<Uri, ByteBuffer> uriBuffer =
+ prepareFontData(context, fonts, cancellationSignal);
+ return new Typeface.Builder(fonts, uriBuffer).build();
+ }
+
+ /**
+ * A helper function to create a mapping from {@link Uri} to {@link ByteBuffer}.
+ *
+ * Skip if the file contents is not ready to be read.
+ *
+ * @param context A {@link Context} to be used for resolving content URI in
+ * {@link FontInfo}.
+ * @param fonts An array of {@link FontInfo}.
+ * @return A map from {@link Uri} to {@link ByteBuffer}.
+ */
+ private static Map<Uri, ByteBuffer> prepareFontData(Context context, FontInfo[] fonts,
+ CancellationSignal cancellationSignal) {
+ final HashMap<Uri, ByteBuffer> out = new HashMap<>();
+ final ContentResolver resolver = context.getContentResolver();
+
+ for (FontInfo font : fonts) {
+ if (font.getResultCode() != Columns.RESULT_CODE_OK) {
+ continue;
+ }
+
+ final Uri uri = font.getUri();
+ if (out.containsKey(uri)) {
+ continue;
+ }
+
+ ByteBuffer buffer = null;
+ try (final ParcelFileDescriptor pfd =
+ resolver.openFileDescriptor(uri, "r", cancellationSignal);
+ final FileInputStream fis = new FileInputStream(pfd.getFileDescriptor())) {
+ final FileChannel fileChannel = fis.getChannel();
+ final long size = fileChannel.size();
+ buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
+ } catch (IOException e) {
+ // ignore
+ }
+
+ // TODO: try other approach?, e.g. read all contents instead of mmap.
+
+ out.put(uri, buffer);
+ }
+ return Collections.unmodifiableMap(out);
+ }
+
/** @hide */
@VisibleForTesting
- public ProviderInfo getProvider(FontRequest request, ResultReceiver receiver) {
+ public static @Nullable ProviderInfo getProvider(
+ PackageManager packageManager, FontRequest request) throws NameNotFoundException {
String providerAuthority = request.getProviderAuthority();
- ProviderInfo info = mPackageManager.resolveContentProvider(providerAuthority, 0);
+ ProviderInfo info = packageManager.resolveContentProvider(providerAuthority, 0);
if (info == null) {
- Log.e(TAG, "Can't find content provider " + providerAuthority);
- receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
- return null;
+ throw new NameNotFoundException("No package found for authority: " + providerAuthority);
}
if (!info.packageName.equals(request.getProviderPackage())) {
- Log.e(TAG, "Found content provider " + providerAuthority + ", but package was not "
- + request.getProviderPackage());
- receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
- return null;
+ throw new NameNotFoundException("Found content provider " + providerAuthority
+ + ", but package was not " + request.getProviderPackage());
}
// Trust system apps without signature checks
if (info.applicationInfo.isSystemApp()) {
@@ -221,16 +541,11 @@
}
List<byte[]> signatures;
- try {
- PackageInfo packageInfo = mPackageManager.getPackageInfo(info.packageName,
- PackageManager.GET_SIGNATURES);
- signatures = convertToByteArrayList(packageInfo.signatures);
- Collections.sort(signatures, sByteArrayComparator);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Can't find content provider " + providerAuthority, e);
- receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
- return null;
- }
+ PackageInfo packageInfo = packageManager.getPackageInfo(info.packageName,
+ PackageManager.GET_SIGNATURES);
+ signatures = convertToByteArrayList(packageInfo.signatures);
+ Collections.sort(signatures, sByteArrayComparator);
+
List<List<byte[]>> requestCertificatesList = request.getCertificates();
for (int i = 0; i < requestCertificatesList.size(); ++i) {
// Make a copy so we can sort it without modifying the incoming data.
@@ -240,8 +555,6 @@
return info;
}
}
- Log.e(TAG, "Certificates don't match for given provider " + providerAuthority);
- receiver.send(RESULT_CODE_WRONG_CERTIFICATES, null);
return null;
}
@@ -257,7 +570,8 @@
return 0;
};
- private boolean equalsByteArrayList(List<byte[]> signatures, List<byte[]> requestSignatures) {
+ private static boolean equalsByteArrayList(
+ List<byte[]> signatures, List<byte[]> requestSignatures) {
if (signatures.size() != requestSignatures.size()) {
return false;
}
@@ -269,7 +583,7 @@
return true;
}
- private List<byte[]> convertToByteArrayList(Signature[] signatures) {
+ private static List<byte[]> convertToByteArrayList(Signature[] signatures) {
List<byte[]> shas = new ArrayList<>();
for (int i = 0; i < signatures.length; ++i) {
shas.add(signatures[i].toByteArray());
@@ -279,84 +593,70 @@
/** @hide */
@VisibleForTesting
- public void getFontFromProvider(FontRequest request, ResultReceiver receiver,
- String authority) {
- ArrayList<FontResult> result = null;
- Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ public static @NonNull FontInfo[] getFontFromProvider(
+ Context context, FontRequest request, String authority,
+ CancellationSignal cancellationSignal) throws InvalidFormatException {
+ ArrayList<FontInfo> result = new ArrayList<>();
+ final Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.build();
- try (Cursor cursor = mContext.getContentResolver().query(uri, new String[] { Columns._ID,
- Columns.TTC_INDEX, Columns.VARIATION_SETTINGS, Columns.STYLE,
- Columns.WEIGHT, Columns.ITALIC, Columns.RESULT_CODE },
- "query = ?", new String[] { request.getQuery() }, null);) {
+ final Uri fileBaseUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority)
+ .appendPath("file")
+ .build();
+ try (Cursor cursor = context.getContentResolver().query(uri, new String[] { Columns._ID,
+ Columns.FILE_ID, Columns.TTC_INDEX, Columns.VARIATION_SETTINGS,
+ Columns.STYLE, Columns.WEIGHT, Columns.ITALIC, Columns.RESULT_CODE },
+ "query = ?", new String[] { request.getQuery() }, null, cancellationSignal);) {
// TODO: Should we restrict the amount of fonts that can be returned?
// TODO: Write documentation explaining that all results should be from the same family.
if (cursor != null && cursor.getCount() > 0) {
final int resultCodeColumnIndex = cursor.getColumnIndex(Columns.RESULT_CODE);
- int resultCode = -1;
result = new ArrayList<>();
final int idColumnIndex = cursor.getColumnIndexOrThrow(Columns._ID);
+ final int fileIdColumnIndex = cursor.getColumnIndex(Columns.FILE_ID);
final int ttcIndexColumnIndex = cursor.getColumnIndex(Columns.TTC_INDEX);
final int vsColumnIndex = cursor.getColumnIndex(Columns.VARIATION_SETTINGS);
final int weightColumnIndex = cursor.getColumnIndex(Columns.WEIGHT);
final int italicColumnIndex = cursor.getColumnIndex(Columns.ITALIC);
final int styleColumnIndex = cursor.getColumnIndex(Columns.STYLE);
while (cursor.moveToNext()) {
- resultCode = resultCodeColumnIndex != -1
+ int resultCode = resultCodeColumnIndex != -1
? cursor.getInt(resultCodeColumnIndex) : Columns.RESULT_CODE_OK;
- if (resultCode != Columns.RESULT_CODE_OK) {
- if (resultCode < 0) {
- // Negative values are reserved for the internal errors.
- resultCode = Columns.RESULT_CODE_FONT_NOT_FOUND;
- }
- for (int i = 0; i < result.size(); ++i) {
- try {
- result.get(i).getFileDescriptor().close();
- } catch (IOException e) {
- // Ignore, as we are closing fds for cleanup.
- }
- }
- receiver.send(resultCode, null);
- return;
+ final int ttcIndex = ttcIndexColumnIndex != -1
+ ? cursor.getInt(ttcIndexColumnIndex) : 0;
+ final String variationSettings = vsColumnIndex != -1
+ ? cursor.getString(vsColumnIndex) : null;
+
+ Uri fileUri;
+ if (fileIdColumnIndex == -1) {
+ long id = cursor.getLong(idColumnIndex);
+ fileUri = ContentUris.withAppendedId(uri, id);
+ } else {
+ long id = cursor.getLong(fileIdColumnIndex);
+ fileUri = ContentUris.withAppendedId(fileBaseUri, id);
}
- long id = cursor.getLong(idColumnIndex);
- Uri fileUri = ContentUris.withAppendedId(uri, id);
- try {
- ParcelFileDescriptor pfd =
- mContext.getContentResolver().openFileDescriptor(fileUri, "r");
- final int ttcIndex = ttcIndexColumnIndex != -1
- ? cursor.getInt(ttcIndexColumnIndex) : 0;
- final String variationSettings = vsColumnIndex != -1
- ? cursor.getString(vsColumnIndex) : null;
- // TODO: Stop using STYLE column and enforce WEIGHT/ITALIC column.
- int weight;
- boolean italic;
- if (weightColumnIndex != -1 && italicColumnIndex != -1) {
- weight = cursor.getInt(weightColumnIndex);
- italic = cursor.getInt(italicColumnIndex) == 1;
- } else if (styleColumnIndex != -1) {
- final int style = cursor.getInt(styleColumnIndex);
- weight = (style & Typeface.BOLD) != 0 ? 700 : 400;
- italic = (style & Typeface.ITALIC) != 0;
- } else {
- weight = 400;
- italic = false;
- }
- result.add(
- new FontResult(pfd, ttcIndex, variationSettings, weight, italic));
- } catch (FileNotFoundException e) {
- Log.e(TAG, "FileNotFoundException raised when interacting with content "
- + "provider " + authority, e);
+ // TODO: Stop using STYLE column and enforce WEIGHT/ITALIC column.
+ int weight;
+ boolean italic;
+ if (weightColumnIndex != -1 && italicColumnIndex != -1) {
+ weight = cursor.getInt(weightColumnIndex);
+ italic = cursor.getInt(italicColumnIndex) == 1;
+ } else if (styleColumnIndex != -1) {
+ final int style = cursor.getInt(styleColumnIndex);
+ weight = (style & Typeface.BOLD) != 0 ?
+ Typeface.Builder.BOLD_WEIGHT : Typeface.Builder.NORMAL_WEIGHT;
+ italic = (style & Typeface.ITALIC) != 0;
+ } else {
+ weight = Typeface.Builder.NORMAL_WEIGHT;
+ italic = false;
}
+ FontVariationAxis[] axes =
+ FontVariationAxis.fromFontVariationSettings(variationSettings);
+ result.add(new FontInfo(fileUri, ttcIndex, axes, weight, italic, resultCode));
}
}
}
- if (result != null && !result.isEmpty()) {
- Bundle bundle = new Bundle();
- bundle.putParcelableArrayList(PARCEL_FONT_RESULTS, result);
- receiver.send(Columns.RESULT_CODE_OK, bundle);
- return;
- }
- receiver.send(Columns.RESULT_CODE_FONT_NOT_FOUND, null);
+ return result.toArray(new FontInfo[0]);
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 287ab9e..6c46f2e 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4125,6 +4125,7 @@
INSTANT_APP_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED);
INSTANT_APP_SETTINGS.add(TIME_12_24);
INSTANT_APP_SETTINGS.add(SOUND_EFFECTS_ENABLED);
+ INSTANT_APP_SETTINGS.add(ACCELEROMETER_ROTATION);
}
/**
@@ -6922,7 +6923,8 @@
*
* @hide
*/
- public static final String WEB_ACTION_ENABLED = "web_action_enabled";
+ @SystemApi
+ public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled";
/**
* Has this pairable device been paired or upgraded from a previously paired system.
@@ -7093,6 +7095,7 @@
INSTANT_APP_SETTINGS.add(ANDROID_ID);
INSTANT_APP_SETTINGS.add(PACKAGE_VERIFIER_USER_CONSENT);
+ INSTANT_APP_SETTINGS.add(ALLOW_MOCK_LOCATION);
}
/**
@@ -10330,6 +10333,7 @@
INSTANT_APP_SETTINGS.add(TRANSITION_ANIMATION_SCALE);
INSTANT_APP_SETTINGS.add(ANIMATOR_DURATION_SCALE);
INSTANT_APP_SETTINGS.add(DEBUG_VIEW_ATTRIBUTES);
+ INSTANT_APP_SETTINGS.add(WTF_IS_FATAL);
}
/**
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 3117f98..eab0d4c 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -309,7 +309,6 @@
return this;
}
-
/**
* Builds a new {@link FillResponse} instance. You must provide at least
* one dataset or some savable ids or an authentication with a presentation
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java
index 8537d8f..ed58390 100644
--- a/core/java/android/text/FontConfig.java
+++ b/core/java/android/text/FontConfig.java
@@ -23,8 +23,6 @@
import android.annotation.Nullable;
import android.graphics.fonts.FontVariationAxis;
import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
import java.lang.annotation.Retention;
@@ -33,7 +31,7 @@
* Font configuration descriptions for System fonts.
* @hide
*/
-public final class FontConfig implements Parcelable {
+public final class FontConfig {
private final @NonNull Family[] mFamilies;
private final @NonNull Alias[] mAliases;
@@ -57,37 +55,9 @@
}
/**
- * @hide
- */
- public FontConfig(Parcel in) {
- mFamilies = in.readTypedArray(Family.CREATOR);
- mAliases = in.readTypedArray(Alias.CREATOR);
- }
-
- @Override
- public void writeToParcel(Parcel out, int flag) {
- out.writeTypedArray(mFamilies, flag);
- out.writeTypedArray(mAliases, flag);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<FontConfig> CREATOR = new Parcelable.Creator() {
- public FontConfig createFromParcel(Parcel in) {
- return new FontConfig(in);
- }
- public FontConfig[] newArray(int size) {
- return new FontConfig[size];
- }
- };
-
- /**
* Class that holds information about a Font.
*/
- public static final class Font implements Parcelable {
+ public static final class Font {
private final @NonNull String mFontName;
private final int mTtcIndex;
private final @NonNull FontVariationAxis[] mAxes;
@@ -152,57 +122,15 @@
return mUri;
}
- /**
- * @hide
- */
public void setUri(@NonNull Uri uri) {
mUri = uri;
}
-
- /**
- * @hide
- */
- public Font(Parcel in) {
- mFontName = in.readString();
- mTtcIndex = in.readInt();
- mAxes = in.createTypedArray(FontVariationAxis.CREATOR);
- mWeight = in.readInt();
- mIsItalic = in.readInt() == 1;
- mUri = in.readTypedObject(Uri.CREATOR);
- }
-
- @Override
- public void writeToParcel(Parcel out, int flag) {
- out.writeString(mFontName);
- out.writeInt(mTtcIndex);
- out.writeTypedArray(mAxes, flag);
- out.writeInt(mWeight);
- out.writeInt(mIsItalic ? 1 : 0);
- out.writeTypedObject(mUri, flag);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Creator<Font> CREATOR = new Creator<Font>() {
- @Override
- public Font createFromParcel(Parcel in) {
- return new Font(in);
- }
-
- @Override
- public Font[] newArray(int size) {
- return new Font[size];
- }
- };
}
/**
* Class that holds information about a Font alias.
*/
- public static final class Alias implements Parcelable {
+ public static final class Alias {
private final @NonNull String mName;
private final @NonNull String mToName;
private final int mWeight;
@@ -233,45 +161,12 @@
public int getWeight() {
return mWeight;
}
-
- /**
- * @hide
- */
- public Alias(Parcel in) {
- mName = in.readString();
- mToName = in.readString();
- mWeight = in.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel out, int flag) {
- out.writeString(mName);
- out.writeString(mToName);
- out.writeInt(mWeight);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Creator<Alias> CREATOR = new Creator<Alias>() {
- @Override
- public Alias createFromParcel(Parcel in) {
- return new Alias(in);
- }
-
- @Override
- public Alias[] newArray(int size) {
- return new Alias[size];
- }
- };
}
/**
* Class that holds information about a Font family.
*/
- public static final class Family implements Parcelable {
+ public static final class Family {
private final @NonNull String mName;
private final @NonNull Font[] mFonts;
private final @NonNull String mLanguage;
@@ -343,40 +238,5 @@
public @Variant int getVariant() {
return mVariant;
}
-
- /**
- * @hide
- */
- public Family(Parcel in) {
- mName = in.readString();
- mFonts = in.readTypedArray(Font.CREATOR);
- mLanguage = in.readString();
- mVariant = in.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel out, int flag) {
- out.writeString(mName);
- out.writeTypedArray(mFonts, flag);
- out.writeString(mLanguage);
- out.writeInt(mVariant);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Creator<Family> CREATOR = new Creator<Family>() {
- @Override
- public Family createFromParcel(Parcel in) {
- return new Family(in);
- }
-
- @Override
- public Family[] newArray(int size) {
- return new Family[size];
- }
- };
}
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index b47fce8..a233ba1 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1030,24 +1030,17 @@
* the paragraph's primary direction.
*/
public float getPrimaryHorizontal(int offset) {
- return getPrimaryHorizontal(offset, false /* not clamped */,
- true /* getNewLineStartPosOnLineBreak */);
+ return getPrimaryHorizontal(offset, false /* not clamped */);
}
/**
* Get the primary horizontal position for the specified text offset, but
* optionally clamp it so that it doesn't exceed the width of the layout.
- *
- * @param offset the offset to get horizontal position
- * @param clamped whether to clamp the position by using the width of this layout.
- * @param getNewLineStartPosOnLineBreak whether to get the start position of new line when the
- * offset is at automatic line break.
* @hide
*/
- public float getPrimaryHorizontal(int offset, boolean clamped,
- boolean getNewLineStartPosOnLineBreak) {
+ public float getPrimaryHorizontal(int offset, boolean clamped) {
boolean trailing = primaryIsTrailingPrevious(offset);
- return getHorizontal(offset, trailing, clamped, getNewLineStartPosOnLineBreak);
+ return getHorizontal(offset, trailing, clamped);
}
/**
@@ -1056,37 +1049,26 @@
* the direction other than the paragraph's primary direction.
*/
public float getSecondaryHorizontal(int offset) {
- return getSecondaryHorizontal(offset, false /* not clamped */,
- true /* getNewLineStartPosOnLineBreak */);
+ return getSecondaryHorizontal(offset, false /* not clamped */);
}
/**
* Get the secondary horizontal position for the specified text offset, but
* optionally clamp it so that it doesn't exceed the width of the layout.
- *
- * @param offset the offset to get horizontal position
- * @param clamped whether to clamp the position by using the width of this layout.
- * @param getNewLineStartPosOnLineBreak whether to get the start position of new line when the
- * offset is at automatic line break.
* @hide
*/
- public float getSecondaryHorizontal(int offset, boolean clamped,
- boolean getNewLineStartPosOnLineBreak) {
+ public float getSecondaryHorizontal(int offset, boolean clamped) {
boolean trailing = primaryIsTrailingPrevious(offset);
- return getHorizontal(offset, !trailing, clamped, getNewLineStartPosOnLineBreak);
+ return getHorizontal(offset, !trailing, clamped);
}
- private float getHorizontal(int offset, boolean primary,
- boolean getNewLineStartPosOnLineBreak) {
- return primary ? getPrimaryHorizontal(offset, false /* not clamped */,
- getNewLineStartPosOnLineBreak)
- : getSecondaryHorizontal(offset, false /* not clamped */,
- getNewLineStartPosOnLineBreak);
+ private float getHorizontal(int offset, boolean primary) {
+ return primary ? getPrimaryHorizontal(offset) : getSecondaryHorizontal(offset);
}
- private float getHorizontal(int offset, boolean trailing, boolean clamped,
- boolean getNewLineStartPosOnLineBreak) {
- final int line = getLineForOffset(offset, getNewLineStartPosOnLineBreak);
+ private float getHorizontal(int offset, boolean trailing, boolean clamped) {
+ int line = getLineForOffset(offset);
+
return getHorizontal(offset, trailing, line, clamped);
}
@@ -1300,10 +1282,6 @@
* beyond the end of the text, you get the last line.
*/
public int getLineForOffset(int offset) {
- return getLineForOffset(offset, true);
- }
-
- private int getLineForOffset(int offset, boolean getNewLineOnLineBreak) {
int high = getLineCount(), low = -1, guess;
while (high - low > 1) {
@@ -1318,10 +1296,6 @@
if (low < 0) {
return 0;
} else {
- if (!getNewLineOnLineBreak && low > 0 && getLineStart(low) == offset
- && mText.charAt(offset - 1) != '\n') {
- return low - 1;
- }
return low;
}
}
@@ -1357,14 +1331,14 @@
false, null);
final int max;
- if (line != getLineCount() - 1 && mText.charAt(lineEndOffset - 1) == '\n') {
+ if (line == getLineCount() - 1) {
+ max = lineEndOffset;
+ } else {
max = tl.getOffsetToLeftRightOf(lineEndOffset - lineStartOffset,
!isRtlCharAt(lineEndOffset - 1)) + lineStartOffset;
- } else {
- max = lineEndOffset;
}
int best = lineStartOffset;
- float bestdist = Math.abs(getHorizontal(best, primary, true) - horiz);
+ float bestdist = Math.abs(getHorizontal(best, primary) - horiz);
for (int i = 0; i < dirs.mDirections.length; i += 2) {
int here = lineStartOffset + dirs.mDirections[i];
@@ -1380,9 +1354,7 @@
guess = (high + low) / 2;
int adguess = getOffsetAtStartOf(guess);
- if (getHorizontal(adguess, primary,
- adguess == lineStartOffset || adguess != lineEndOffset) * swap
- >= horiz * swap) {
+ if (getHorizontal(adguess, primary) * swap >= horiz * swap) {
high = guess;
} else {
low = guess;
@@ -1396,11 +1368,9 @@
int aft = tl.getOffsetToLeftRightOf(low - lineStartOffset, isRtl) + lineStartOffset;
low = tl.getOffsetToLeftRightOf(aft - lineStartOffset, !isRtl) + lineStartOffset;
if (low >= here && low < there) {
- float dist = Math.abs(getHorizontal(low, primary,
- low == lineStartOffset || low != lineEndOffset) - horiz);
+ float dist = Math.abs(getHorizontal(low, primary) - horiz);
if (aft < there) {
- float other = Math.abs(getHorizontal(aft, primary,
- aft == lineStartOffset || aft != lineEndOffset) - horiz);
+ float other = Math.abs(getHorizontal(aft, primary) - horiz);
if (other < dist) {
dist = other;
@@ -1415,8 +1385,7 @@
}
}
- float dist = Math.abs(getHorizontal(here, primary,
- here == lineStartOffset || here != lineEndOffset) - horiz);
+ float dist = Math.abs(getHorizontal(here, primary) - horiz);
if (dist < bestdist) {
bestdist = dist;
@@ -1424,10 +1393,10 @@
}
}
- float dist = Math.abs(getHorizontal(max, primary,
- max == lineStartOffset || max != lineEndOffset) - horiz);
+ float dist = Math.abs(getHorizontal(max, primary) - horiz);
if (dist <= bestdist) {
+ bestdist = dist;
best = max;
}
@@ -1621,9 +1590,8 @@
int bottom = getLineTop(line+1);
boolean clamped = shouldClampCursor(line);
- float h1 = getPrimaryHorizontal(point, clamped, true) - 0.5f;
- float h2 = isLevelBoundary(point)
- ? getSecondaryHorizontal(point, clamped, true) - 0.5f : h1;
+ float h1 = getPrimaryHorizontal(point, clamped) - 0.5f;
+ float h2 = isLevelBoundary(point) ? getSecondaryHorizontal(point, clamped) - 0.5f : h1;
int caps = TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SHIFT_ON) |
TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SELECTING);
@@ -1740,7 +1708,8 @@
}
int startline = getLineForOffset(start);
- int endline = getLineForOffset(end, false);
+ int endline = getLineForOffset(end);
+
int top = getLineTop(startline);
int bottom = getLineBottom(endline);
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 5f01f7b..d41dfdc 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -98,7 +98,7 @@
if (en > end - start)
en = end - start;
- setSpan(false, spans[i], st, en, fl);
+ setSpan(false, spans[i], st, en, fl, false/*enforceParagraph*/);
}
restoreInvariants();
}
@@ -355,7 +355,8 @@
}
if (spanStart != ost || spanEnd != oen) {
- setSpan(false, mSpans[i], spanStart, spanEnd, mSpanFlags[i]);
+ setSpan(false, mSpans[i], spanStart, spanEnd, mSpanFlags[i],
+ true/*enforceParagraph*/);
changed = true;
}
}
@@ -430,13 +431,8 @@
int copySpanEnd = en - csStart + start;
int copySpanFlags = sp.getSpanFlags(spans[i]) | SPAN_ADDED;
- int flagsStart = (copySpanFlags & START_MASK) >> START_SHIFT;
- int flagsEnd = copySpanFlags & END_MASK;
-
- if(!isInvalidParagraphStart(copySpanStart, flagsStart) &&
- !isInvalidParagraphEnd(copySpanEnd, flagsEnd)) {
- setSpan(false, spans[i], copySpanStart, copySpanEnd, copySpanFlags);
- }
+ setSpan(false, spans[i], copySpanStart, copySpanEnd, copySpanFlags,
+ false/*enforceParagraph*/);
}
}
restoreInvariants();
@@ -558,7 +554,7 @@
changed = true;
setSpan(false, Selection.SELECTION_START, selectionStart, selectionStart,
- Spanned.SPAN_POINT_POINT);
+ Spanned.SPAN_POINT_POINT, true/*enforceParagraph*/);
}
if (selectionEnd > start && selectionEnd < end) {
final long diff = selectionEnd - start;
@@ -567,7 +563,7 @@
changed = true;
setSpan(false, Selection.SELECTION_END, selectionEnd, selectionEnd,
- Spanned.SPAN_POINT_POINT);
+ Spanned.SPAN_POINT_POINT, true/*enforceParagraph*/);
}
if (changed) {
restoreInvariants();
@@ -673,23 +669,34 @@
* inserted at the start or end of the span's range.
*/
public void setSpan(Object what, int start, int end, int flags) {
- setSpan(true, what, start, end, flags);
+ setSpan(true, what, start, end, flags, true/*enforceParagraph*/);
}
// Note: if send is false, then it is the caller's responsibility to restore
// invariants. If send is false and the span already exists, then this method
// will not change the index of any spans.
- private void setSpan(boolean send, Object what, int start, int end, int flags) {
+ private void setSpan(boolean send, Object what, int start, int end, int flags,
+ boolean enforceParagraph) {
checkRange("setSpan", start, end);
int flagsStart = (flags & START_MASK) >> START_SHIFT;
- if(isInvalidParagraphStart(start, flagsStart)) {
- throw new RuntimeException("PARAGRAPH span must start at paragraph boundary");
+ if (isInvalidParagraph(start, flagsStart)) {
+ if (!enforceParagraph) {
+ // do not set the span
+ return;
+ }
+ throw new RuntimeException("PARAGRAPH span must start at paragraph boundary"
+ + " (" + start + " follows " + charAt(start - 1) + ")");
}
int flagsEnd = flags & END_MASK;
- if(isInvalidParagraphEnd(end, flagsEnd)) {
- throw new RuntimeException("PARAGRAPH span must end at paragraph boundary");
+ if (isInvalidParagraph(end, flagsEnd)) {
+ if (!enforceParagraph) {
+ // do not set the span
+ return;
+ }
+ throw new RuntimeException("PARAGRAPH span must end at paragraph boundary"
+ + " (" + end + " follows " + charAt(end - 1) + ")");
}
// 0-length Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
@@ -767,26 +774,8 @@
}
}
- private final boolean isInvalidParagraphStart(int start, int flagsStart) {
- if (flagsStart == PARAGRAPH) {
- if (start != 0 && start != length()) {
- char c = charAt(start - 1);
-
- if (c != '\n') return true;
- }
- }
- return false;
- }
-
- private final boolean isInvalidParagraphEnd(int end, int flagsEnd) {
- if (flagsEnd == PARAGRAPH) {
- if (end != 0 && end != length()) {
- char c = charAt(end - 1);
-
- if (c != '\n') return true;
- }
- }
- return false;
+ private boolean isInvalidParagraph(int index, int flag) {
+ return flag == PARAGRAPH && index != 0 && index != length() && charAt(index - 1) != '\n';
}
/**
diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java
index 4b02df86..366ec14 100644
--- a/core/java/android/text/SpannableStringInternal.java
+++ b/core/java/android/text/SpannableStringInternal.java
@@ -65,7 +65,7 @@
if (en > end)
en = end;
- setSpan(spans[i], st - start, en - start, fl);
+ setSpan(spans[i], st - start, en - start, fl, false/*enforceParagraph*/);
}
}
@@ -149,28 +149,36 @@
}
/* package */ void setSpan(Object what, int start, int end, int flags) {
+ setSpan(what, start, end, flags, true/*enforceParagraph*/);
+ }
+
+ private boolean isIndexFollowsNextLine(int index) {
+ return index != 0 && index != length() && charAt(index - 1) != '\n';
+ }
+
+ private void setSpan(Object what, int start, int end, int flags, boolean enforceParagraph) {
int nstart = start;
int nend = end;
checkRange("setSpan", start, end);
if ((flags & Spannable.SPAN_PARAGRAPH) == Spannable.SPAN_PARAGRAPH) {
- if (start != 0 && start != length()) {
- char c = charAt(start - 1);
-
- if (c != '\n')
- throw new RuntimeException(
- "PARAGRAPH span must start at paragraph boundary" +
- " (" + start + " follows " + c + ")");
+ if (isIndexFollowsNextLine(start)) {
+ if (!enforceParagraph) {
+ // do not set the span
+ return;
+ }
+ throw new RuntimeException("PARAGRAPH span must start at paragraph boundary"
+ + " (" + start + " follows " + charAt(start - 1) + ")");
}
- if (end != 0 && end != length()) {
- char c = charAt(end - 1);
-
- if (c != '\n')
- throw new RuntimeException(
- "PARAGRAPH span must end at paragraph boundary" +
- " (" + end + " follows " + c + ")");
+ if (isIndexFollowsNextLine(end)) {
+ if (!enforceParagraph) {
+ // do not set the span
+ return;
+ }
+ throw new RuntimeException("PARAGRAPH span must end at paragraph boundary"
+ + " (" + end + " follows " + charAt(end - 1) + ")");
}
}
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 7e6eb49..0f85159 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -88,7 +88,11 @@
* {@link android.webkit.WebView#findAddress(String) findAddress()} method in
* {@link android.webkit.WebView} for finding addresses, which has various
* limitations.
+ *
+ * @deprecated See {@link android.webkit.WebView#findAddress(String) findAddress()}
+ * for more explanation.
*/
+ @Deprecated
public static final int MAP_ADDRESSES = 0x08;
/**
diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java
index b6d8aa4..546f93a 100644
--- a/core/java/android/transition/ChangeBounds.java
+++ b/core/java/android/transition/ChangeBounds.java
@@ -472,9 +472,9 @@
private int mTop;
private int mRight;
private int mBottom;
- private boolean mIsTopLeftSet;
- private boolean mIsBottomRightSet;
private View mView;
+ private int mTopLeftCalls;
+ private int mBottomRightCalls;
public ViewBounds(View view) {
mView = view;
@@ -483,8 +483,8 @@
public void setTopLeft(PointF topLeft) {
mLeft = Math.round(topLeft.x);
mTop = Math.round(topLeft.y);
- mIsTopLeftSet = true;
- if (mIsBottomRightSet) {
+ mTopLeftCalls++;
+ if (mTopLeftCalls == mBottomRightCalls) {
setLeftTopRightBottom();
}
}
@@ -492,16 +492,16 @@
public void setBottomRight(PointF bottomRight) {
mRight = Math.round(bottomRight.x);
mBottom = Math.round(bottomRight.y);
- mIsBottomRightSet = true;
- if (mIsTopLeftSet) {
+ mBottomRightCalls++;
+ if (mTopLeftCalls == mBottomRightCalls) {
setLeftTopRightBottom();
}
}
private void setLeftTopRightBottom() {
mView.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
- mIsTopLeftSet = false;
- mIsBottomRightSet = false;
+ mTopLeftCalls = 0;
+ mBottomRightCalls = 0;
}
}
}
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 5bc6c94..d857bf7 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -212,7 +212,9 @@
* @param tag The tag to check.
* @param level The level to check.
* @return Whether or not that this is allowed to be logged.
- * @throws IllegalArgumentException is thrown if the tag.length() > 23.
+ * @throws IllegalArgumentException is thrown if the tag.length() > 23
+ * for Nougat (7.0) releases (API <= 23) and prior, there is no
+ * tag limit of concern after this API level.
*/
public static native boolean isLoggable(String tag, int level);
diff --git a/core/java/android/util/StateSet.java b/core/java/android/util/StateSet.java
index 051de8a..4bbc0f8 100644
--- a/core/java/android/util/StateSet.java
+++ b/core/java/android/util/StateSet.java
@@ -228,6 +228,29 @@
return true;
}
+ /**
+ * Check whether a list of state specs has an attribute specified.
+ * @param stateSpecs a list of state specs we're checking.
+ * @param attr an attribute we're looking for.
+ * @return {@code true} if the attribute is contained in the state specs.
+ * @hide
+ */
+ public static boolean containsAttribute(int[][] stateSpecs, int attr) {
+ if (stateSpecs != null) {
+ for (int[] spec : stateSpecs) {
+ if (spec == null) {
+ break;
+ }
+ for (int specAttr : spec) {
+ if (specAttr == attr || -specAttr == attr) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
public static int[] trimStateSet(int[] states, int newSize) {
if (states.length == newSize) {
return states;
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index f3c2421..7792939 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -21,8 +21,7 @@
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.util.ArrayMap;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
+import android.util.ArraySet;
import java.util.ArrayList;
import java.util.Collections;
@@ -54,9 +53,11 @@
final Rect mOtherRect = new Rect();
final Rect mBestCandidateRect = new Rect();
private final UserSpecifiedFocusComparator mUserSpecifiedFocusComparator =
- new UserSpecifiedFocusComparator((v) -> v.getNextFocusForwardId());
+ new UserSpecifiedFocusComparator((r, v) -> isValidId(v.getNextFocusForwardId())
+ ? v.findUserSetNextFocus(r, View.FOCUS_FORWARD) : null);
private final UserSpecifiedFocusComparator mUserSpecifiedClusterComparator =
- new UserSpecifiedFocusComparator((v) -> v.getNextClusterForwardId());
+ new UserSpecifiedFocusComparator((r, v) -> isValidId(v.getNextClusterForwardId())
+ ? v.findUserSetNextKeyboardNavigationCluster(r, View.FOCUS_FORWARD) : null);
private final FocusComparator mFocusComparator = new FocusComparator();
private final ArrayList<View> mTempList = new ArrayList<View>();
@@ -258,7 +259,7 @@
@View.FocusDirection int direction) {
try {
// Note: This sort is stable.
- mUserSpecifiedClusterComparator.setFocusables(clusters);
+ mUserSpecifiedClusterComparator.setFocusables(clusters, root);
Collections.sort(clusters, mUserSpecifiedClusterComparator);
} finally {
mUserSpecifiedClusterComparator.recycle();
@@ -283,7 +284,7 @@
View focused, Rect focusedRect, int direction) {
try {
// Note: This sort is stable.
- mUserSpecifiedFocusComparator.setFocusables(focusables);
+ mUserSpecifiedFocusComparator.setFocusables(focusables, root);
Collections.sort(focusables, mUserSpecifiedFocusComparator);
} finally {
mUserSpecifiedFocusComparator.recycle();
@@ -823,56 +824,55 @@
* specified focus chains (eg. no nextFocusForward attributes defined), this should be a no-op.
*/
private static final class UserSpecifiedFocusComparator implements Comparator<View> {
- private final SparseArray<View> mFocusables = new SparseArray<View>();
- private final SparseBooleanArray mIsConnectedTo = new SparseBooleanArray();
+ private final ArrayMap<View, View> mNextFoci = new ArrayMap<>();
+ private final ArraySet<View> mIsConnectedTo = new ArraySet<>();
private final ArrayMap<View, View> mHeadsOfChains = new ArrayMap<View, View>();
private final ArrayMap<View, Integer> mOriginalOrdinal = new ArrayMap<>();
- private final NextIdGetter mNextIdGetter;
+ private final NextFocusGetter mNextFocusGetter;
+ private View mRoot;
- public interface NextIdGetter {
- int get(View view);
+ public interface NextFocusGetter {
+ View get(View root, View view);
}
- UserSpecifiedFocusComparator(NextIdGetter nextIdGetter) {
- mNextIdGetter = nextIdGetter;
+ UserSpecifiedFocusComparator(NextFocusGetter nextFocusGetter) {
+ mNextFocusGetter = nextFocusGetter;
}
public void recycle() {
- mFocusables.clear();
+ mRoot = null;
mHeadsOfChains.clear();
mIsConnectedTo.clear();
mOriginalOrdinal.clear();
+ mNextFoci.clear();
}
- public void setFocusables(List<View> focusables) {
- for (int i = focusables.size() - 1; i >= 0; i--) {
- final View view = focusables.get(i);
- final int id = view.getId();
- if (isValidId(id)) {
- mFocusables.put(id, view);
- }
- final int nextId = mNextIdGetter.get(view);
- if (isValidId(nextId)) {
- mIsConnectedTo.put(nextId, true);
- }
- }
-
- for (int i = focusables.size() - 1; i >= 0; i--) {
- final View view = focusables.get(i);
- final int nextId = mNextIdGetter.get(view);
- if (isValidId(nextId) && !mIsConnectedTo.get(view.getId())) {
- setHeadOfChain(view);
- }
- }
-
+ public void setFocusables(List<View> focusables, View root) {
+ mRoot = root;
for (int i = 0; i < focusables.size(); ++i) {
mOriginalOrdinal.put(focusables.get(i), i);
}
+
+ for (int i = focusables.size() - 1; i >= 0; i--) {
+ final View view = focusables.get(i);
+ final View next = mNextFocusGetter.get(mRoot, view);
+ if (next != null && mOriginalOrdinal.containsKey(next)) {
+ mNextFoci.put(view, next);
+ mIsConnectedTo.add(next);
+ }
+ }
+
+ for (int i = focusables.size() - 1; i >= 0; i--) {
+ final View view = focusables.get(i);
+ final View next = mNextFoci.get(view);
+ if (next != null && !mIsConnectedTo.contains(view)) {
+ setHeadOfChain(view);
+ }
+ }
}
private void setHeadOfChain(View head) {
- for (View view = head; view != null;
- view = mFocusables.get(mNextIdGetter.get(view))) {
+ for (View view = head; view != null; view = mNextFoci.get(view)) {
final View otherHead = mHeadsOfChains.get(view);
if (otherHead != null) {
if (otherHead == head) {
@@ -900,7 +900,7 @@
return -1; // first is the head, it should be first
} else if (second == firstHead) {
return 1; // second is the head, it should be first
- } else if (isValidId(mNextIdGetter.get(first))) {
+ } else if (mNextFoci.get(first) != null) {
return -1; // first is not the end of the chain
} else {
return 1; // first is end of chain
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 1cb563f..3b15456 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -55,6 +55,8 @@
private static native void nativeSetAnimationTransaction();
private static native void nativeSetLayer(long nativeObject, int zorder);
+ private static native void nativeSetRelativeLayer(long nativeObject, IBinder relativeTo,
+ int zorder);
private static native void nativeSetPosition(long nativeObject, float x, float y);
private static native void nativeSetGeometryAppliesWithResize(long nativeObject);
private static native void nativeSetSize(long nativeObject, int w, int h);
@@ -461,6 +463,11 @@
nativeSetLayer(mNativeObject, zorder);
}
+ public void setRelativeLayer(IBinder relativeTo, int zorder) {
+ checkNotReleased();
+ nativeSetRelativeLayer(mNativeObject, relativeTo, zorder);
+ }
+
public void setPosition(float x, float y) {
checkNotReleased();
nativeSetPosition(mNativeObject, x, y);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 076b33c..1a71679 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -93,7 +93,7 @@
* artifacts may occur on previous versions of the platform when its window is
* positioned asynchronously.</p>
*/
-public class SurfaceView extends View {
+public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
private static final String TAG = "SurfaceView";
private static final boolean DEBUG = false;
@@ -169,6 +169,8 @@
boolean mWindowVisibility = false;
boolean mLastWindowVisibility = false;
boolean mViewVisibility = false;
+ boolean mWindowStopped = false;
+
int mRequestedWidth = -1;
int mRequestedHeight = -1;
/* Set SurfaceView's format to 565 by default to maintain backward
@@ -226,12 +228,27 @@
return mSurfaceHolder;
}
+ private void updateRequestedVisibility() {
+ mRequestedVisible = mViewVisibility && mWindowVisibility && !mWindowStopped;
+ }
+
+ /** @hide */
+ @Override
+ public void windowStopped(boolean stopped) {
+ mWindowStopped = stopped;
+ updateRequestedVisibility();
+ updateSurface();
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+
+ getViewRootImpl().addWindowStoppedCallback(this);
+
mParent.requestTransparentRegion(this);
mViewVisibility = getVisibility() == VISIBLE;
- mRequestedVisible = mViewVisibility && mWindowVisibility;
+ updateRequestedVisibility();
mAttachedToWindow = true;
if (!mGlobalListenersAdded) {
@@ -246,7 +263,7 @@
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
mWindowVisibility = visibility == VISIBLE;
- mRequestedVisible = mWindowVisibility && mViewVisibility;
+ updateRequestedVisibility();
updateSurface();
}
@@ -254,7 +271,7 @@
public void setVisibility(int visibility) {
super.setVisibility(visibility);
mViewVisibility = visibility == VISIBLE;
- boolean newRequestedVisible = mWindowVisibility && mViewVisibility;
+ boolean newRequestedVisible = mWindowVisibility && mViewVisibility && !mWindowStopped;
if (newRequestedVisible != mRequestedVisible) {
// our base class (View) invalidates the layout only when
// we go from/to the GONE state. However, SurfaceView needs
@@ -278,6 +295,8 @@
@Override
protected void onDetachedFromWindow() {
+ getViewRootImpl().removeWindowStoppedCallback(this);
+
mAttachedToWindow = false;
if (mGlobalListenersAdded) {
ViewTreeObserver observer = getViewTreeObserver();
@@ -299,6 +318,7 @@
mSurfaceControl = null;
mHaveFrame = false;
+
super.onDetachedFromWindow();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a09db9c..9072bf9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3920,6 +3920,14 @@
private int mBackgroundResource;
private boolean mBackgroundSizeChanged;
+ /** The default focus highlight.
+ * @see #mDefaultFocusHighlightEnabled
+ * @see Drawable#hasFocusStateSpecified()
+ */
+ private Drawable mDefaultFocusHighlight;
+ private Drawable mDefaultFocusHighlightCache;
+ private boolean mDefaultFocusHighlightSizeChanged;
+
private String mTransitionName;
static class TintInfo {
@@ -4102,6 +4110,12 @@
*/
int mNextClusterForwardId = View.NO_ID;
+ /**
+ * Whether this View should use a default focus highlight when it gets focused but doesn't
+ * have {@link android.R.attr#state_focused} defined in its background.
+ */
+ boolean mDefaultFocusHighlightEnabled = true;
+
private CheckForLongPress mPendingCheckForLongPress;
private CheckForTap mPendingCheckForTap = null;
private PerformClick mPerformClick;
@@ -5086,6 +5100,11 @@
setImportantForAutofill(a.getInt(attr, IMPORTANT_FOR_AUTOFILL_AUTO));
}
break;
+ case R.styleable.View_defaultFocusHighlightEnabled:
+ if (a.peekValue(attr) != null) {
+ setDefaultFocusHighlightEnabled(a.getBoolean(attr, true));
+ }
+ break;
}
}
@@ -6800,6 +6819,9 @@
AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
}
+ // Here we check whether we still need the default focus highlight, and switch it on/off.
+ switchDefaultFocusHighlight();
+
InputMethodManager imm = InputMethodManager.peekInstance();
if (!gainFocus) {
if (isPressed()) {
@@ -9986,6 +10008,33 @@
}
/**
+ * Sets whether this View should use a default focus highlight when it gets focused but doesn't
+ * have {@link android.R.attr#state_focused} defined in its background.
+ *
+ * @param defaultFocusHighlightEnabled {@code true} to set this view to use a default focus
+ * highlight, {@code false} otherwise.
+ *
+ * @attr ref android.R.styleable#View_defaultFocusHighlightEnabled
+ */
+ public void setDefaultFocusHighlightEnabled(boolean defaultFocusHighlightEnabled) {
+ mDefaultFocusHighlightEnabled = defaultFocusHighlightEnabled;
+ }
+
+ /**
+
+ /**
+ * Returns whether this View should use a default focus highlight when it gets focused but
+ * doesn't have {@link android.R.attr#state_focused} defined in its background.
+ *
+ * @return True if this View should use a default focus highlight.
+ * @attr ref android.R.styleable#View_defaultFocusHighlightEnabled
+ */
+ @ViewDebug.ExportedProperty(category = "defaultFocusHighlightEnabled")
+ public final boolean getDefaultFocusHighlightEnabled() {
+ return mDefaultFocusHighlightEnabled;
+ }
+
+ /**
* If a user manually specified the next view id for a particular direction,
* use the root to look up the view.
* @param root The root view of the hierarchy containing this view.
@@ -11752,6 +11801,10 @@
if (dr != null && isVisible != dr.isVisible()) {
dr.setVisible(isVisible, false);
}
+ final Drawable hl = mDefaultFocusHighlight;
+ if (hl != null && isVisible != hl.isVisible()) {
+ hl.setVisible(isVisible, false);
+ }
final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
if (fg != null && isVisible != fg.isVisible()) {
fg.setVisible(isVisible, false);
@@ -12965,6 +13018,7 @@
if ((changed & DRAW_MASK) != 0) {
if ((mViewFlags & WILL_NOT_DRAW) != 0) {
if (mBackground != null
+ || mDefaultFocusHighlight != null
|| (mForegroundInfo != null && mForegroundInfo.mDrawable != null)) {
mPrivateFlags &= ~PFLAG_SKIP_DRAW;
} else {
@@ -13036,6 +13090,7 @@
}
mBackgroundSizeChanged = true;
+ mDefaultFocusHighlightSizeChanged = true;
if (mForegroundInfo != null) {
mForegroundInfo.mBoundsChanged = true;
}
@@ -13927,6 +13982,7 @@
invalidate(true);
}
mBackgroundSizeChanged = true;
+ mDefaultFocusHighlightSizeChanged = true;
if (mForegroundInfo != null) {
mForegroundInfo.mBoundsChanged = true;
}
@@ -13995,6 +14051,7 @@
invalidate(true);
}
mBackgroundSizeChanged = true;
+ mDefaultFocusHighlightSizeChanged = true;
if (mForegroundInfo != null) {
mForegroundInfo.mBoundsChanged = true;
}
@@ -14057,6 +14114,7 @@
invalidate(true);
}
mBackgroundSizeChanged = true;
+ mDefaultFocusHighlightSizeChanged = true;
if (mForegroundInfo != null) {
mForegroundInfo.mBoundsChanged = true;
}
@@ -14116,6 +14174,7 @@
invalidate(true);
}
mBackgroundSizeChanged = true;
+ mDefaultFocusHighlightSizeChanged = true;
if (mForegroundInfo != null) {
mForegroundInfo.mBoundsChanged = true;
}
@@ -18720,6 +18779,9 @@
// Step 6, draw decorations (foreground, scrollbars)
onDrawForeground(canvas);
+ // Step 7, draw the default focus highlight
+ drawDefaultFocusHighlight(canvas);
+
if (debugDraw()) {
debugDrawFocus(canvas);
}
@@ -19278,6 +19340,7 @@
mPrivateFlags |= drawn;
mBackgroundSizeChanged = true;
+ mDefaultFocusHighlightSizeChanged = true;
if (mForegroundInfo != null) {
mForegroundInfo.mBoundsChanged = true;
}
@@ -19429,6 +19492,9 @@
if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
mForegroundInfo.mDrawable.setLayoutDirection(layoutDirection);
}
+ if (mDefaultFocusHighlight != null) {
+ mDefaultFocusHighlight.setLayoutDirection(layoutDirection);
+ }
mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
onResolveDrawables(layoutDirection);
}
@@ -19487,7 +19553,8 @@
// Avoid verifying the scroll bar drawable so that we don't end up in
// an invalidation loop. This effectively prevents the scroll bar
// drawable from triggering invalidations and scheduling runnables.
- return who == mBackground || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
+ return who == mBackground || (mForegroundInfo != null && mForegroundInfo.mDrawable == who)
+ || (mDefaultFocusHighlight == who);
}
/**
@@ -19511,6 +19578,11 @@
changed |= bg.setState(state);
}
+ final Drawable hl = mDefaultFocusHighlight;
+ if (hl != null && hl.isStateful()) {
+ changed |= hl.setState(state);
+ }
+
final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
if (fg != null && fg.isStateful()) {
changed |= fg.setState(state);
@@ -19550,6 +19622,9 @@
if (mBackground != null) {
mBackground.setHotspot(x, y);
}
+ if (mDefaultFocusHighlight != null) {
+ mDefaultFocusHighlight.setHotspot(x, y);
+ }
if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
mForegroundInfo.mDrawable.setHotspot(x, y);
}
@@ -19586,6 +19661,106 @@
}
/**
+ * Create a default focus highlight if it doesn't exist.
+ * @return a default focus highlight.
+ */
+ private Drawable getDefaultFocusHighlightDrawable() {
+ if (mDefaultFocusHighlightCache == null) {
+ if (mContext != null) {
+ final int[] attrs = new int[] { android.R.attr.selectableItemBackground };
+ final TypedArray ta = mContext.obtainStyledAttributes(attrs);
+ mDefaultFocusHighlightCache = ta.getDrawable(0);
+ ta.recycle();
+ }
+ }
+ return mDefaultFocusHighlightCache;
+ }
+
+ /**
+ * Set the current default focus highlight.
+ * @param highlight the highlight drawable, or {@code null} if it's no longer needed.
+ */
+ private void setDefaultFocusHighlight(Drawable highlight) {
+ mDefaultFocusHighlight = highlight;
+ mDefaultFocusHighlightSizeChanged = true;
+ if (highlight != null) {
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
+ mPrivateFlags &= ~PFLAG_SKIP_DRAW;
+ }
+ highlight.setLayoutDirection(getLayoutDirection());
+ if (highlight.isStateful()) {
+ highlight.setState(getDrawableState());
+ }
+ if (isAttachedToWindow()) {
+ highlight.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
+ }
+ // Set callback last, since the view may still be initializing.
+ highlight.setCallback(this);
+ } else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null
+ && (mForegroundInfo == null || mForegroundInfo.mDrawable == null)) {
+ mPrivateFlags |= PFLAG_SKIP_DRAW;
+ }
+ requestLayout();
+ invalidate();
+ }
+
+ /**
+ * Check whether we need to draw a default focus highlight when this view gets focused,
+ * which requires:
+ * <ul>
+ * <li>In the background, {@link android.R.attr#state_focused} is not defined.</li>
+ * <li>This view is not in touch mode.</li>
+ * <li>This view doesn't opt out for a default focus highlight, via
+ * {@link #setDefaultFocusHighlightEnabled(boolean)}.</li>
+ * <li>This view is attached to window.</li>
+ * </ul>
+ * @return {@code true} if a default focus highlight is needed.
+ */
+ private boolean isDefaultFocusHighlightNeeded(Drawable background) {
+ final boolean hasFocusStateSpecified = background == null || !background.isStateful()
+ || !background.hasFocusStateSpecified();
+ return !isInTouchMode() && getDefaultFocusHighlightEnabled() && hasFocusStateSpecified
+ && isAttachedToWindow();
+ }
+
+ /**
+ * When this view is focused, switches on/off the default focused highlight.
+ * <p>
+ * This always happens when this view is focused, and only at this moment the default focus
+ * highlight can be visible.
+ */
+ private void switchDefaultFocusHighlight() {
+ if (isFocused()) {
+ final boolean needed = isDefaultFocusHighlightNeeded(mBackground);
+ final boolean active = mDefaultFocusHighlight != null;
+ if (needed && !active) {
+ setDefaultFocusHighlight(getDefaultFocusHighlightDrawable());
+ } else if (!needed && active) {
+ // The highlight is no longer needed, so tear it down.
+ setDefaultFocusHighlight(null);
+ }
+ }
+ }
+
+ /**
+ * Draw the default focus highlight onto the canvas.
+ * @param canvas the canvas where we're drawing the highlight.
+ */
+ private void drawDefaultFocusHighlight(Canvas canvas) {
+ if (mDefaultFocusHighlight != null) {
+ if (mDefaultFocusHighlightSizeChanged) {
+ mDefaultFocusHighlightSizeChanged = false;
+ final int l = mScrollX;
+ final int r = l + mRight - mLeft;
+ final int t = mScrollY;
+ final int b = t + mBottom - mTop;
+ mDefaultFocusHighlight.setBounds(l, t, r, b);
+ }
+ mDefaultFocusHighlight.draw(canvas);
+ }
+ }
+
+ /**
* Return an array of resource IDs of the drawable states representing the
* current state of the view.
*
@@ -19725,6 +19900,9 @@
if (mStateListAnimator != null) {
mStateListAnimator.jumpToCurrentState();
}
+ if (mDefaultFocusHighlight != null) {
+ mDefaultFocusHighlight.jumpToCurrentState();
+ }
if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
mForegroundInfo.mDrawable.jumpToCurrentState();
}
@@ -19869,6 +20047,7 @@
/* Remove the background */
mBackground = null;
if ((mViewFlags & WILL_NOT_DRAW) != 0
+ && (mDefaultFocusHighlight == null)
&& (mForegroundInfo == null || mForegroundInfo.mDrawable == null)) {
mPrivateFlags |= PFLAG_SKIP_DRAW;
}
@@ -20060,7 +20239,8 @@
}
// Set callback last, since the view may still be initializing.
foreground.setCallback(this);
- } else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null) {
+ } else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null
+ && (mDefaultFocusHighlight == null)) {
mPrivateFlags |= PFLAG_SKIP_DRAW;
}
requestLayout();
@@ -21875,6 +22055,11 @@
// Similarly, we remove the foreground drawable's non-transparent parts.
applyDrawableToTransparentRegion(mForegroundInfo.mDrawable, region);
}
+ if (mDefaultFocusHighlight != null
+ && mDefaultFocusHighlight.getOpacity() != PixelFormat.TRANSPARENT) {
+ // Similarly, we remove the default focus highlight's non-transparent parts.
+ applyDrawableToTransparentRegion(mDefaultFocusHighlight, region);
+ }
}
}
return true;
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 574137b..4def0d0 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -35,7 +35,7 @@
* Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
* dips
*/
- private static final int SCROLL_BAR_SIZE = 4;
+ private static final int SCROLL_BAR_SIZE = 10;
/**
* Duration of the fade when scrollbars fade away in milliseconds
@@ -354,8 +354,7 @@
mEdgeSlop = (int) (sizeAndDensity * EDGE_SLOP + 0.5f);
mFadingEdgeLength = (int) (sizeAndDensity * FADING_EDGE_LENGTH + 0.5f);
- mScrollbarSize = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_scrollbarSize);
+ mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f);
mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f);
mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 58ef0af..a7ececf 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1249,6 +1249,19 @@
mIsAmbientMode = ambient;
}
+ interface WindowStoppedCallback {
+ public void windowStopped(boolean stopped);
+ }
+ private final ArrayList<WindowStoppedCallback> mWindowStoppedCallbacks = new ArrayList<>();
+
+ void addWindowStoppedCallback(WindowStoppedCallback c) {
+ mWindowStoppedCallbacks.add(c);
+ }
+
+ void removeWindowStoppedCallback(WindowStoppedCallback c) {
+ mWindowStoppedCallbacks.remove(c);
+ }
+
void setWindowStopped(boolean stopped) {
if (mStopped != stopped) {
mStopped = stopped;
@@ -1264,6 +1277,10 @@
renderer.destroyHardwareResources(mView);
}
}
+
+ for (int i = 0; i < mWindowStoppedCallbacks.size(); i++) {
+ mWindowStoppedCallbacks.get(i).windowStopped(stopped);
+ }
}
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index ba004b96..e85a658 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -192,6 +192,9 @@
* {@hide}
*/
public void onCreate(Bundle savedInstanceState) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
mLastAutofilledData = savedInstanceState.getParcelable(LAST_AUTOFILLED_DATA_TAG);
@@ -237,6 +240,9 @@
* {@hide}
*/
public void onAttachedToWindow(@NonNull IBinder windowToken) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (mSessionId == NO_SESSION) {
return;
@@ -258,6 +264,9 @@
* {@hide}
*/
public void onSaveInstanceState(Bundle outState) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (mSessionId != NO_SESSION) {
outState.putInt(SESSION_ID_TAG, mSessionId);
@@ -278,6 +287,9 @@
* @return whether autofill is enabled for the current user.
*/
public boolean isEnabled() {
+ if (!hasAutofillFeature()) {
+ return false;
+ }
synchronized (mLock) {
ensureServiceClientAddedIfNeededLocked();
return mEnabled;
@@ -294,6 +306,9 @@
* @param view view requesting the new autofill context.
*/
public void requestAutofill(@NonNull View view) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
ensureServiceClientAddedIfNeededLocked();
@@ -320,6 +335,9 @@
* @param bounds child boundaries, relative to the top window.
*/
public void requestAutofill(@NonNull View view, int childId, @NonNull Rect bounds) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
ensureServiceClientAddedIfNeededLocked();
@@ -339,6 +357,9 @@
* @param view {@link View} that was entered.
*/
public void notifyViewEntered(@NonNull View view) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
AutofillCallback callback = null;
synchronized (mLock) {
ensureServiceClientAddedIfNeededLocked();
@@ -372,6 +393,9 @@
* @param view {@link View} that was exited.
*/
public void notifyViewExited(@NonNull View view) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
ensureServiceClientAddedIfNeededLocked();
@@ -392,6 +416,9 @@
* @param bounds child boundaries, relative to the top window.
*/
public void notifyViewEntered(@NonNull View view, int childId, @NonNull Rect bounds) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
AutofillCallback callback = null;
synchronized (mLock) {
ensureServiceClientAddedIfNeededLocked();
@@ -426,6 +453,9 @@
* @param childId id identifying the virtual child inside the view.
*/
public void notifyViewExited(@NonNull View view, int childId) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
ensureServiceClientAddedIfNeededLocked();
@@ -444,6 +474,9 @@
* @param view view whose value changed.
*/
public void notifyValueChanged(View view) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
AutofillId id = null;
boolean valueWasRead = false;
AutofillValue value = null;
@@ -486,7 +519,6 @@
}
}
-
/**
* Called to indicate the value of an autofillable virtual {@link View} changed.
*
@@ -495,6 +527,9 @@
* @param value new value of the child.
*/
public void notifyValueChanged(View view, int childId, AutofillValue value) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (!mEnabled || mSessionId == NO_SESSION) {
return;
@@ -512,6 +547,9 @@
* call this method after the form is submitted and another page is rendered.
*/
public void commit() {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (!mEnabled && mSessionId == NO_SESSION) {
return;
@@ -528,6 +566,9 @@
* call this method if the user does not post the form but moves to another form in this page.
*/
public void cancel() {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (!mEnabled && mSessionId == NO_SESSION) {
return;
@@ -542,6 +583,9 @@
* will be disabled.
*/
public void disableOwnedAutofillServices() {
+ if (!hasAutofillFeature()) {
+ return;
+ }
try {
mService.disableOwnedAutofillServices(mContext.getUserId());
} catch (RemoteException e) {
@@ -558,6 +602,9 @@
/** @hide */
public void onAuthenticationResult(Intent data) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
// TODO(b/33197203): the result code is being ignored, so this method is not reliably
// handling the cases where it's not RESULT_OK: it works fine if the service does not
// set the EXTRA_AUTHENTICATION_RESULT extra, but it could cause weird results if the
@@ -672,6 +719,9 @@
* @param callback callback to receive events.
*/
public void registerCallback(@Nullable AutofillCallback callback) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (callback == null) return;
@@ -694,6 +744,9 @@
* @param callback callback to stop receiving events.
*/
public void unregisterCallback(@Nullable AutofillCallback callback) {
+ if (!hasAutofillFeature()) {
+ return;
+ }
synchronized (mLock) {
if (callback == null || mCallback == null || callback != mCallback) return;
@@ -871,6 +924,10 @@
return view;
}
+ private boolean hasAutofillFeature() {
+ return mService != null;
+ }
+
/**
* Callback for auto-fill related events.
*
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 71809bd..f0645b8 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -57,7 +57,6 @@
* @attr ref android.R.styleable#InputMethod_settingsActivity
* @attr ref android.R.styleable#InputMethod_isDefault
* @attr ref android.R.styleable#InputMethod_supportsSwitchingToNextInputMethod
- * @attr ref android.R.styleable#InputMethod_supportsDismissingWindow
*/
public final class InputMethodInfo implements Parcelable {
static final String TAG = "InputMethodInfo";
@@ -105,11 +104,6 @@
private final boolean mSupportsSwitchingToNextInputMethod;
/**
- * The flag whether this IME supports ways to dismiss its window (e.g. dismiss button.)
- */
- private final boolean mSupportsDismissingWindow;
-
- /**
* @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
* @return a unique ID to be returned by {@link #getId()}. We have used
* {@link ComponentName#flattenToShortString()} for this purpose (and it is already
@@ -151,7 +145,6 @@
mId = computeId(service);
boolean isAuxIme = true;
boolean supportsSwitchingToNextInputMethod = false; // false as default
- boolean supportsDismissingWindow = false; // false as default
mForceDefault = false;
PackageManager pm = context.getPackageManager();
@@ -191,8 +184,6 @@
supportsSwitchingToNextInputMethod = sa.getBoolean(
com.android.internal.R.styleable.InputMethod_supportsSwitchingToNextInputMethod,
false);
- supportsDismissingWindow = sa.getBoolean(
- com.android.internal.R.styleable.InputMethod_supportsDismissingWindow, false);
sa.recycle();
final int depth = parser.getDepth();
@@ -263,7 +254,6 @@
mIsDefaultResId = isDefaultResId;
mIsAuxIme = isAuxIme;
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
- mSupportsDismissingWindow = supportsDismissingWindow;
}
InputMethodInfo(Parcel source) {
@@ -272,7 +262,6 @@
mIsDefaultResId = source.readInt();
mIsAuxIme = source.readInt() == 1;
mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
- mSupportsDismissingWindow = source.readInt() == 1;
mService = ResolveInfo.CREATOR.createFromParcel(source);
mSubtypes = new InputMethodSubtypeArray(source);
mForceDefault = false;
@@ -285,8 +274,7 @@
CharSequence label, String settingsActivity) {
this(buildDummyResolveInfo(packageName, className, label), false /* isAuxIme */,
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
- false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
- true /* supportsDismissingWindow */);
+ false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */);
}
/**
@@ -297,8 +285,7 @@
String settingsActivity, List<InputMethodSubtype> subtypes, int isDefaultResId,
boolean forceDefault) {
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
- true /* supportsSwitchingToNextInputMethod */,
- true /* supportsDismissingWindow */);
+ true /* supportsSwitchingToNextInputMethod */);
}
/**
@@ -307,7 +294,7 @@
*/
public InputMethodInfo(ResolveInfo ri, boolean isAuxIme, String settingsActivity,
List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
- boolean supportsSwitchingToNextInputMethod, boolean supportsDismissingWindow) {
+ boolean supportsSwitchingToNextInputMethod) {
final ServiceInfo si = ri.serviceInfo;
mService = ri;
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
@@ -317,7 +304,6 @@
mSubtypes = new InputMethodSubtypeArray(subtypes);
mForceDefault = forceDefault;
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
- mSupportsDismissingWindow = supportsDismissingWindow;
}
private static ResolveInfo buildDummyResolveInfo(String packageName, String className,
@@ -458,8 +444,7 @@
public void dump(Printer pw, String prefix) {
pw.println(prefix + "mId=" + mId
+ " mSettingsActivityName=" + mSettingsActivityName
- + " mSupportsSwitchingToNextInputMethod=" + mSupportsSwitchingToNextInputMethod
- + " mSupportsDismissingWindow=" + mSupportsDismissingWindow);
+ + " mSupportsSwitchingToNextInputMethod=" + mSupportsSwitchingToNextInputMethod);
pw.println(prefix + "mIsDefaultResId=0x"
+ Integer.toHexString(mIsDefaultResId));
pw.println(prefix + "Service:");
@@ -512,14 +497,6 @@
}
/**
- * @return true if this input method supports ways to dismiss its window.
- * @hide
- */
- public boolean supportsDismissingWindow() {
- return mSupportsDismissingWindow;
- }
-
- /**
* Used to package this object into a {@link Parcel}.
*
* @param dest The {@link Parcel} to be written.
@@ -532,7 +509,6 @@
dest.writeInt(mIsDefaultResId);
dest.writeInt(mIsAuxIme ? 1 : 0);
dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
- dest.writeInt(mSupportsDismissingWindow ? 1 : 0);
mService.writeToParcel(dest, flags);
mSubtypes.writeToParcel(dest);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6213a63..9202889 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1731,7 +1731,14 @@
*
* @param addr the string to search for addresses
* @return the address, or if no address is found, null
+ *
+ * @deprecated findAddress is deprecated. It only supports a subset of US
+ * addresses and has a high false positive rate. Calling findAddress also causes
+ * WebView to be loaded into the app, which significantly increases memory usage
+ * if the app doesn't already use WebView. Use {@link TextClassifier} instead for
+ * classifying text and finding addresses.
*/
+ @Deprecated
public static String findAddress(String addr) {
// TODO: Rewrite this in Java so it is not needed to start up chromium
// Could also be deprecated
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index faa2310..4fb7b19 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1915,11 +1915,10 @@
}
boolean clamped = layout.shouldClampCursor(line);
- updateCursorPosition(0, top, middle, layout.getPrimaryHorizontal(offset, clamped, true));
+ updateCursorPosition(0, top, middle, layout.getPrimaryHorizontal(offset, clamped));
if (mCursorCount == 2) {
- updateCursorPosition(1, middle, bottom,
- layout.getSecondaryHorizontal(offset, clamped, true));
+ updateCursorPosition(1, middle, bottom, layout.getSecondaryHorizontal(offset, clamped));
}
}
@@ -4340,7 +4339,7 @@
updateSelection(offset);
addPositionToTouchUpFilter(offset);
}
- final int line = getLineForOffset(layout, offset);
+ final int line = layout.getLineForOffset(offset);
mPrevLine = line;
mPositionX = getCursorHorizontalPosition(layout, offset) - mHotspotX
@@ -4367,15 +4366,6 @@
return (int) (getHorizontal(layout, offset) - 0.5f);
}
- /**
- * @param layout Text layout.
- * @param offset Character offset for the cursor.
- * @return The line the cursor should be at.
- */
- int getLineForOffset(Layout layout, int offset) {
- return layout.getLineForOffset(offset);
- }
-
@Override
public void updatePosition(int parentPositionX, int parentPositionY,
boolean parentPositionChanged, boolean parentScrolled) {
@@ -4804,7 +4794,7 @@
|| !isStartHandle() && initialOffset <= anotherHandleOffset) {
// Handles have crossed, bound it to the first selected line and
// adjust by word / char as normal.
- currLine = getLineForOffset(layout, anotherHandleOffset, !isStartHandle());
+ currLine = layout.getLineForOffset(anotherHandleOffset);
initialOffset = getOffsetAtCoordinate(layout, currLine, x);
}
@@ -4876,18 +4866,14 @@
if (isExpanding) {
// User is increasing the selection.
int wordBoundary = isStartHandle() ? wordStart : wordEnd;
- final boolean atLineBoundary = layout.getLineStart(currLine) == offset
- || layout.getLineEnd(currLine) == offset;
- final boolean atWordBoundary = getWordIteratorWithText().isBoundary(offset);
- final boolean snapToWord = !(atLineBoundary && atWordBoundary)
- && (!mInWord
- || (isStartHandle() ? currLine < mPrevLine : currLine > mPrevLine))
- && atRtl == isAtRtlRun(layout, wordBoundary);
+ final boolean snapToWord = (!mInWord
+ || (isStartHandle() ? currLine < mPrevLine : currLine > mPrevLine))
+ && atRtl == isAtRtlRun(layout, wordBoundary);
if (snapToWord) {
// Sometimes words can be broken across lines (Chinese, hyphenation).
// We still snap to the word boundary but we only use the letters on the
// current line to determine if the user is far enough into the word to snap.
- if (getLineForOffset(layout, wordBoundary) != currLine) {
+ if (layout.getLineForOffset(wordBoundary) != currLine) {
wordBoundary = isStartHandle()
? layout.getLineStart(currLine) : layout.getLineEnd(currLine);
}
@@ -5035,29 +5021,12 @@
}
private float getHorizontal(@NonNull Layout layout, int offset, boolean startHandle) {
- final int line = getLineForOffset(layout, offset);
+ final int line = layout.getLineForOffset(offset);
final int offsetToCheck = startHandle ? offset : Math.max(offset - 1, 0);
final boolean isRtlChar = layout.isRtlCharAt(offsetToCheck);
final boolean isRtlParagraph = layout.getParagraphDirection(line) == -1;
return (isRtlChar == isRtlParagraph)
- ? layout.getPrimaryHorizontal(offset, false, startHandle)
- : layout.getSecondaryHorizontal(offset, false, startHandle);
- }
-
- @Override
- public int getLineForOffset(@NonNull Layout layout, int offset) {
- return getLineForOffset(layout, offset, isStartHandle());
- }
-
- private int getLineForOffset(@NonNull Layout layout, int offset, boolean startHandle) {
- final int line = layout.getLineForOffset(offset);
- if (!startHandle && line > 0 && layout.getLineStart(line) == offset
- && mTextView.getText().charAt(offset - 1) != '\n') {
- // If end handle is at a line break in a paragraph, the handle should be at the
- // previous line.
- return line - 1;
- }
- return line;
+ ? layout.getPrimaryHorizontal(offset) : layout.getSecondaryHorizontal(offset);
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fcab703..9a8131e 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8470,7 +8470,7 @@
// right where it is most likely to be annoying.
final boolean clamped = grav > 0;
// FIXME: Is it okay to truncate this, or should we round?
- final int x = (int) layout.getPrimaryHorizontal(offset, clamped, true);
+ final int x = (int) layout.getPrimaryHorizontal(offset, clamped);
final int top = layout.getLineTop(line);
final int bottom = layout.getLineTop(line + 1);
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 3a31b37..35d4ba8 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -38,6 +38,7 @@
int checkPackage(int uid, String packageName);
List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
+ List<AppOpsManager.PackageOps> getUidOps(int uid, in int[] ops);
void setUidMode(int code, int uid, int mode);
void setMode(int code, int uid, String packageName, int mode);
void resetAllModes(int reqUserId, String reqPackageName);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 8e6e63b..c4540f5 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -2263,8 +2263,9 @@
@Override
public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> list, int deviceId) {
final PanelFeatureState st = mWindow.getPanelState(FEATURE_OPTIONS_PANEL, false);
- if (!mWindow.isDestroyed() && st != null && mWindow.getCallback() != null) {
- mWindow.getCallback().onProvideKeyboardShortcuts(list, st.menu, deviceId);
+ final Menu menu = st != null ? st.menu : null;
+ if (!mWindow.isDestroyed() && mWindow.getCallback() != null) {
+ mWindow.getCallback().onProvideKeyboardShortcuts(list, menu, deviceId);
}
}
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 8f7908a..d740a76 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -617,6 +617,21 @@
return parcel->getOpenAshmemSize();
}
+static jint android_os_Parcel_compareData(JNIEnv* env, jclass clazz, jlong thisNativePtr,
+ jlong otherNativePtr)
+{
+ Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
+ if (thisParcel == NULL) {
+ return 0;
+ }
+ Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
+ if (otherParcel == NULL) {
+ return thisParcel->getOpenAshmemSize();
+ }
+
+ return thisParcel->compareData(*otherParcel);
+}
+
static jlong android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
jlong otherNativePtr, jint offset, jint length)
{
@@ -781,6 +796,7 @@
{"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall},
{"nativeUnmarshall", "(J[BII)J", (void*)android_os_Parcel_unmarshall},
+ {"nativeCompareData", "(JJ)I", (void*)android_os_Parcel_compareData},
{"nativeAppendFrom", "(JJII)J", (void*)android_os_Parcel_appendFrom},
// @FastNative
{"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index abcd1e7..1aed501 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -192,18 +192,12 @@
if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
/*
- * It's an Error: Reraise the exception, detach this thread, and
- * wait for the fireworks. Die even more blatantly after a minute
- * if the gentler attempt doesn't do the trick.
- *
- * The GetJavaVM function isn't on the "approved" list of JNI calls
- * that can be made while an exception is pending, so we want to
- * get the VM ptr, throw the exception, and then detach the thread.
+ * It's an Error: Reraise the exception and ask the runtime to abort.
+ * This will dump the pending exception as well as all thread traces
+ * to the log.
*/
env->Throw(excep);
- env->ExceptionDescribe();
- ALOGE("Forcefully exiting");
- exit(1);
+ env->FatalError("java.lang.Error thrown during binder transaction.");
}
bail:
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index 20dfe78..56505af 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -58,16 +58,7 @@
return false;
}
- jboolean result = false;
- if ((strlen(chars)+sizeof(LOG_NAMESPACE)) > PROPERTY_KEY_MAX) {
- char buf2[200];
- snprintf(buf2, sizeof(buf2), "Log tag \"%s\" exceeds limit of %zu characters\n",
- chars, PROPERTY_KEY_MAX - sizeof(LOG_NAMESPACE));
-
- jniThrowException(env, "java/lang/IllegalArgumentException", buf2);
- } else {
- result = isLoggable(chars, level);
- }
+ jboolean result = isLoggable(chars, level);
env->ReleaseStringUTFChars(tag, chars);
return result;
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index dc365b4..8b82314 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -289,6 +289,14 @@
}
}
+static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong nativeObject,
+ jobject relativeTo, jint zorder) {
+ auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ sp<IBinder> handle = ibinderForJavaObject(env, relativeTo);
+
+ ctrl->setRelativeLayer(handle, zorder);
+}
+
static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat x, jfloat y) {
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
status_t err = ctrl->setPosition(x, y);
@@ -774,6 +782,8 @@
(void*)nativeSetAnimationTransaction },
{"nativeSetLayer", "(JI)V",
(void*)nativeSetLayer },
+ {"nativeSetRelativeLayer", "(JLandroid/os/IBinder;I)V",
+ (void*)nativeSetRelativeLayer },
{"nativeSetPosition", "(JFF)V",
(void*)nativeSetPosition },
{"nativeSetGeometryAppliesWithResize", "(J)V",
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 98c9e78..ce951de 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -499,7 +499,7 @@
SettingProto automatic_storage_manager_downloads_days_to_retain = 163;
SettingProto qs_tiles = 164;
SettingProto demo_user_setup_complete = 165;
- SettingProto web_action_enabled = 166;
+ SettingProto instant_apps_enabled = 166;
SettingProto device_paired = 167;
}
diff --git a/core/res/res/drawable/autofill_dataset_picker_background.xml b/core/res/res/drawable/autofill_dataset_picker_background.xml
new file mode 100644
index 0000000..b5617e1
--- /dev/null
+++ b/core/res/res/drawable/autofill_dataset_picker_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android">
+ <shape android:shape="rectangle">
+ <corners android:radius="2dp" />
+ <solid android:color="?attr/colorBackground" />
+ </shape>
+</inset>
diff --git a/core/res/res/drawable/autofilled_highlight.xml b/core/res/res/drawable/autofilled_highlight.xml
index c7aacb9..3a2815c 100644
--- a/core/res/res/drawable/autofilled_highlight.xml
+++ b/core/res/res/drawable/autofilled_highlight.xml
@@ -15,12 +15,6 @@
* limitations under the License.
-->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetLeft="4dp"
- android:insetRight="4dp"
- android:insetBottom="4dp"
- android:insetTop="4dp">
- <shape>
- <solid android:color="@color/autofilled_highlight" />
- </shape>
-</inset>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@color/autofilled_highlight" />
+</shape>
diff --git a/core/res/res/drawable/scrollbar_handle_material.xml b/core/res/res/drawable/scrollbar_handle_material.xml
index f020112..33efbbac 100644
--- a/core/res/res/drawable/scrollbar_handle_material.xml
+++ b/core/res/res/drawable/scrollbar_handle_material.xml
@@ -19,4 +19,7 @@
android:shape="rectangle">
<solid
android:color="#84ffffff" />
+ <size
+ android:width="4dp"
+ android:height="4dp" />
</shape>
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index 133265b..5a835b7 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -14,11 +14,17 @@
limitations under the License.
-->
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/autofill_dataset_picker"
- android:layout_width="wrap_content"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:divider="@null"
- android:background="#ffffffff"
- android:elevation="@dimen/floating_window_z">
-</ListView>
+ style="@style/AutofillDatasetPicker">
+
+ <ListView
+ android:id="@+id/autofill_dataset_list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:divider="@null"
+ android:visibility="gone">
+ </ListView>
+
+</FrameLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 59e183f..3359b5d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Skakel oor na teksmodus vir die tydinvoer."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Skakel oor na horlosiemodus vir die tydinvoer."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Outovulopsies"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Inhoud kan nie outomaties ingevul word nie"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Stoor na <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Stoor <xliff:g id="TYPE">%1$s</xliff:g> na <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Stoor"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nee, dankie"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"wagwoord"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adres"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kredietkaart"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"gebruikernaam"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-posadres"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Bly kalm en soek skuiling naby."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ontruim kusgebiede en riviergebiede dadelik en gaan na \'n veiliger plek, soos \'n hoogliggende omgewing."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bly kalm en soek skuiling naby."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 07d03ce..8e247aeb 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ለጊዜ ግቤቱ ወደ የጽሑፍ ግቤት ሁነታ ቀይር።"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ለጊዜ ግቤቱ ወደ የሰዓት ሁነታ ቀይር።"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"የራስ-ሙላ አማራጮች"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ይዘቶች በራስ-ሰር ሊሞሉ አይችሉም"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"ወደ <xliff:g id="LABEL">%1$s</xliff:g> ይቀመጥ?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ወደ <xliff:g id="LABEL">%2$s</xliff:g> ይቀመጥ?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"አስቀምጥ"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"አይ፣ አመሰግናለሁ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"የይለፍ ቃል"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"አድራሻ"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ክሬዲት ካርድ"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"የተጠቃሚ ስም"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"የኢሜይል አድራሻ"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"ረጋ ይበሉና በአቅራቢያ ያለ መጠለያ ይፈልጉ።"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ወዲያውኑ ከባህር ዳርቻ አካባቢዎች እና የወንዝ ዳርቻ አካባቢዎች ይውጡና እንደ ከፍ ያለ መሬት ያሉ ከአደጋ የተሻለ ደህንነት ወዳቸው ቦታዎች ይሂዱ።"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ረጋ ይበሉና በአቅራቢያ ያለ መጠለያ ይፈልጉ።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 06ac681..9c42197 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1856,19 +1856,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"يُرجى التبديل إلى وضع إدخال النص لإدخال الوقت."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"يُرجى التبديل إلى وضع الساعة لإدخال الوقت."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"خيارات الملء التلقائي"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"يتعذر إجراء ملء تلقائي للمحتويات"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"هل تريد الحفظ في <xliff:g id="LABEL">%1$s</xliff:g>؟"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"هل تريد حفظ <xliff:g id="TYPE">%1$s</xliff:g> في <xliff:g id="LABEL">%2$s</xliff:g>؟"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"حفظ"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"لا، شكرًا"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"كلمة مرور"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"عنوان"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"بطاقة ائتمان"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"اسم المستخدم"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"عنوان البريد الإلكتروني"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"يُرجى الثبات والبحث عن ملاذ بالجوار."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"يُرجى النزوح في الحال من المناطق الساحلية وضفاف النهر إلى مكان أكثر أمانًا مثل الأراضي المرتفعة."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"يُرجى الثبات والبحث عن ملاذ بالجوار."</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 1d137d0..c2a0690 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Zamanı daxil etmək üçün mətnlə daxiletmə rejiminə keçin"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Zamanı daxil etmək üçün saat rejiminə keçin"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Avtodoldurma seçimləri"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Kontentlər avtomatik olaraq doldurula bilməz"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> etiketində yadda saxlanılsın?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="LABEL">%2$s</xliff:g> etiketində yadda saxlanılsın?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Yadda saxlayın"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Xeyr, çox sağ olun"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"parol"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ünvan"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kredit kartı"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"istifadəçi adı"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-poçt ünvanı"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Sakit qalın və yaxınlıqda sığınacaq axtarın."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Dərhal sahil bölgələrindən və çay kənarı ərazilərdən daha təhlükəsiz yüksək yerlərə evakuasiya edin."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sakit qalın və yaxınlıqda sığınacaq axtarın."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 8828633..86bb518 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -90,17 +90,16 @@
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: Nije ograničen."</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Usluga nije dobavljena."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete da promenite podešavanje ID-a korisnika."</string>
- <string name="RestrictedOnData" msgid="8653794784690065540">"Usluga za podatke je blokirana."</string>
- <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Usluga za hitne slučajeve je blokirana."</string>
- <string name="RestrictedOnNormal" msgid="4953867011389750673">"Glasovna usluga je blokirana."</string>
- <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Sve glasovne usluge su blokirane."</string>
- <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS usluga je blokirana."</string>
- <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Glasovna usluga/usluga prenosa podataka su blokirane."</string>
- <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Glasovna usluga i SMS usluga su blokirane."</string>
- <string name="RestrictedOnAll" msgid="5643028264466092821">"Sve glasovne i SMS usluge, kao i usluge prenosa podataka su blokirane."</string>
+ <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nema usluge prenosa podataka"</string>
+ <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nema usluge za hitne pozive"</string>
+ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nema glasovne usluge"</string>
+ <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema glasovne usluge/usluge za hitne pozive"</string>
+ <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Mobilni operater je privremeno suspendovao uslugu prenosa podataka na ovoj lokaciji"</string>
+ <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Mobilni operater je privremeno suspendovao hitne pozive na ovoj lokaciji"</string>
+ <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Mobilni operater je privremeno suspendovao glasovne pozive na ovoj lokaciji"</string>
+ <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Mobilni operater je privremeno suspendovao glasovne i hitne pozive na ovoj lokaciji"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezivanje sa mrežom nije uspelo"</string>
- <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
- <skip />
+ <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Da biste poboljšali prijem, probajte da promenite izabrani tip u odeljku Sistem > Mreža i internet > Mobilne mreže > Željeni tip mreže."</string>
<string name="peerTtyModeFull" msgid="6165351790010341421">"Korisnik zahteva POTPUN režim TTY"</string>
<string name="peerTtyModeHco" msgid="5728602160669216784">"Korisnik zahteva PRENOS ZVUKA za režim TTY"</string>
<string name="peerTtyModeVco" msgid="1742404978686538049">"Korisnik zahteva PRENOS GLASA za režim TTY"</string>
@@ -140,8 +139,7 @@
</string-array>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
- <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
- <skip />
+ <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Želim mobilne podatke"</string>
<string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -180,18 +178,16 @@
<item quantity="other">Instalirani su autoriteti za izdavanje sertifikata</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od strane nepoznate treće strane"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Od strane administratora profila za posao"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Od strane administratora profila za Work"</string>
<string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od strane <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5005572078641980632">"Poslovni profil je izbrisan"</string>
- <string name="work_profile_deleted_description" msgid="6305147513054341102">"Poslovni profil je izbrisan jer nedostaje administratorska aplikacija."</string>
- <string name="work_profile_deleted_details" msgid="226615743462361248">"Administratorska aplikacija poslovnog profila nedostaje ili je oštećena. Zbog toga su vaš poslovni profil i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
- <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Profil za Work više nije dostupan na ovom uređaju."</string>
- <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
- <skip />
- <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
- <skip />
+ <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profil za Work je izbrisan jer nedostaje aplikacija za administratore"</string>
+ <string name="work_profile_deleted_details" msgid="6307630639269092360">"Aplikacija za administratore na profilu za Work nedostaje ili je oštećena. Zbog toga su profil za Work i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
+ <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Profil za Work više nije dostupan na ovom uređaju"</string>
+ <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja"</string>
+ <string name="network_logging_notification_text" msgid="7930089249949354026">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
<string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti obrisan"</string>
- <string name="factory_reset_message" msgid="4905025204141900666">"Administratorskoj aplikaciji nedostaju neke komponente ili je oštećena i ne može da se koristi. Uređaj će sada biti obrisan. Obratite se administratoru za pomoć."</string>
+ <string name="factory_reset_message" msgid="7972496262232832457">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string>
<string name="me" msgid="6545696007631404292">"Ja"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije za tablet"</string>
<string name="power_dialog" product="tv" msgid="6153888706430556356">"Opcije za TV"</string>
@@ -413,8 +409,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Dozvoljava aplikaciji da pristupa funkcijama telefona na uređaju. Ova dozvola omogućava aplikaciji da utvrdi broj telefona i ID-ove uređaja, zatim da li je poziv aktivan, kao i broj daljinskog uređaja sa kojim je uspostavljen poziv."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"preusmeravanje poziva preko sistema"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dozvoljava aplikaciji da preusmerava pozive preko sistema da bi poboljšala doživljaj pozivanja."</string>
- <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"čitanje broja telefona"</string>
- <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Dozvoljava aplikaciji da pristupa broju telefona na uređaju."</string>
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje brojeva telefona"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Dozvoljava aplikaciji da pristupa brojevima telefona na uređaju."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"sprečavanje prelaska tableta u stanje spavanja"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"sprečavanje TV-a da pređe u stanje spavanja"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečavanje prelaska telefona u stanje spavanja"</string>
@@ -554,7 +550,7 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Podešavanje pravila za lozinku"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
- <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledanje pokušaja otključavanja ekrana"</string>
+ <string name="policylab_watchLogin" msgid="5091404125971980158">"Nadgledajte pokušaje otključavanja ekrana"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Nadgleda broj netačnih lozinki koje unesete pri otključavanju ekrana i zaključava TV ili briše sve podatke sa njega ako se unese previše netačnih lozinki."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava telefon ili briše sve podatke sa telefona ako je netačna lozinka uneta previše puta."</string>
@@ -990,8 +986,7 @@
<string name="selectTextMode" msgid="1018691815143165326">"Izaberi tekst"</string>
<string name="undo" msgid="7905788502491742328">"Opozovi"</string>
<string name="redo" msgid="7759464876566803888">"Ponovi"</string>
- <!-- no translation found for autofill (3035779615680565188) -->
- <skip />
+ <string name="autofill" msgid="3035779615680565188">"Automatsko popunjavanje"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Izbor teksta"</string>
<string name="addToDictionary" msgid="4352161534510057874">"Dodaj u rečnik"</string>
<string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
@@ -1123,7 +1118,13 @@
<string name="network_switch_metered" msgid="4671730921726992671">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
<string name="network_switch_metered_detail" msgid="5325661434777870353">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
<string name="network_switch_metered_toast" msgid="5779283181685974304">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+ <string-array name="network_switch_type_name">
+ <item msgid="3979506840912951943">"mobilni podaci"</item>
+ <item msgid="75483255295529161">"Wi-Fi"</item>
+ <item msgid="6862614801537202646">"Bluetooth"</item>
+ <item msgid="5447331121797802871">"Eternet"</item>
+ <item msgid="8257233890381651999">"VPN"</item>
+ </string-array>
<string name="network_switch_type_name_unknown" msgid="4552612897806660656">"nepoznat tip mreže"</string>
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nije moguće povezati sa Wi-Fi mrežom"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internet vezu."</string>
@@ -1193,7 +1194,7 @@
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izveštaj o grešci se generiše…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li da podelite izveštaj o grešci?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deli se izveštaj o grešci…"</string>
- <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
+ <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
<string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELI"</string>
<string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBIJ"</string>
<string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string>
@@ -1204,7 +1205,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikacija <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplikacija"</string>
- <string name="alert_windows_notification_title" msgid="4532185840598192445">"Aplik. <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplik."</string>
+ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplik."</string>
<string name="alert_windows_notification_message" msgid="8917232109522912560">"Ako ne želite ovu funkciju za <xliff:g id="NAME">%s</xliff:g>, dodirnite da biste otvorili podešavanja i isključili je."</string>
<string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> se priprema"</string>
@@ -1380,8 +1381,7 @@
<string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za potrošnju i podešavanja."</string>
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Nema više 2G-3G podataka"</string>
<string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Nema više 4G podataka"</string>
- <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
- <skip />
+ <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dostigli ste ograničenje podataka"</string>
<string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Nema više Wi-Fi podataka"</string>
<string name="data_usage_limit_body" msgid="291731708279614081">"Potrošili ste podatke za ovaj mesec"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Prekoračen prenos 2G-3G podataka"</string>
@@ -1480,18 +1480,21 @@
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
<string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
- <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Prečica za pristupačnost je UKLJUČENA"</string>
- <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Uključite ili isključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tako što ćete istovremeno zadržati oba dugmeta za jačinu zvuka 3 sekunde.\n\nMožete da promenite uslugu u odeljku Podešavanja > Pristupačnost."</string>
- <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Isključi prečicu"</string>
- <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Ostavi uključeno"</string>
+ <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Želite li da koristite prečicu za pristupačnost?"</string>
+ <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti.\n\n Aktuelna funkcija pristupačnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Možete da promenite funkciju u odeljku Podešavanja > Pristupačnost."</string>
+ <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Isključi prečicu"</string>
+ <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Koristi prečicu"</string>
<string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
+ <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pritisnite i zadržite dugme za pristupačnost da biste menjali funkcije."</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
<string name="user_switched" msgid="3768006783166984410">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="8939524935808875155">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
<string name="error_message_title" msgid="4510373083082500195">"Greška"</string>
- <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administrator nije dozvolio ovu promenu"</string>
+ <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Administrator nije dozvolio ovu promenu"</string>
<string name="app_not_found" msgid="3429141853498927379">"Nije pronađena nijedna aplikacija koja bi mogla da obavi ovu radnju"</string>
<string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
<string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1583,7 +1586,7 @@
<string name="reason_service_unavailable" msgid="7824008732243903268">"Usluga štampanja nije omogućena"</string>
<string name="print_service_installed_title" msgid="2246317169444081628">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
<string name="print_service_installed_message" msgid="5897362931070459152">"Dodirnite da biste omogućili"</string>
- <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite PIN administratora"</string>
+ <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Unesite PIN administratora"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
<string name="restr_pin_incorrect" msgid="8571512003955077924">"Netačno"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuelni PIN"</string>
@@ -1612,16 +1615,16 @@
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> na poslu"</string>
<string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="lock_to_app_toast" msgid="7693684144593484">"Da biste otkačili ovaj ekran, dodirnite i zadržite Nazad i Pregled."</string>
- <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je zakačena: otkačinjanje nije dozvoljeno na ovom uređaju."</string>
+ <string name="lock_to_app_toast" msgid="6820571533009838261">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Pregled"</string>
+ <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ova aplikacija ne može da se otkači"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string>
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN pre otkačinjanja"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži šablon za otključavanje pre otkačinjanja"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku pre otkačinjanja"</string>
- <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao je vaš administrator"</string>
- <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao je administrator"</string>
- <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao je vaš admiistrator"</string>
+ <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao je administrator"</string>
+ <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je administrator"</string>
+ <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je administrator"</string>
<string name="battery_saver_description" msgid="1960431123816253034">"Da bi produžila vreme trajanja baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih podataka. Imejl, razmena poruka i druge aplikacije koje se oslanjaju na sinhronizaciju možda neće da se ažuriraju ako ih ne otvorite.\n\nUšteda baterije se automatski isključuje kada se uređaj puni."</string>
<string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
@@ -1715,8 +1718,8 @@
<string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
<string name="region_picker_section_all" msgid="8966316787153001779">"Svi regioni"</string>
<string name="locale_search_menu" msgid="2560710726687249178">"Pretraži"</string>
- <string name="work_mode_off_title" msgid="8954725060677558855">"Režim za Work je ISKLJUČEN"</string>
- <string name="work_mode_off_message" msgid="3286169091278094476">"Dozvoljava profilu za Work da funkcioniše, uključujući aplikacije, sinhronizaciju u pozadini i srodne funkcije."</string>
+ <string name="work_mode_off_title" msgid="2615362773958585967">"Uključiti režim za Work?"</string>
+ <string name="work_mode_off_message" msgid="2961559609199223594">"Ovo će uključiti profil za Work, uključujući aplikacije, sinhronizaciju u pozadini i srodne funkcije."</string>
<string name="work_mode_turn_on" msgid="2062544985670564875">"Uključi"</string>
<string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite aplikaciju za SMS da biste pregledali"</string>
@@ -1759,22 +1762,26 @@
<string name="time_picker_prompt_label" msgid="7588093983899966783">"Unesite vreme"</string>
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Pređite u režim unosa teksta radi unosa vremena."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Pređite u režim sata radi unosa vremena."</string>
- <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
- <skip />
+ <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcije automatskog popunjavanja"</string>
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sadržaj ne može automatski da se popuni"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Želite li da sačuvate u: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Želite li da sačuvate stavku <xliff:g id="TYPE">%1$s</xliff:g> u: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> u <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Sačuvaj"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"lozinka"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditna kartica"</string>
- <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"korisničko ime"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"imejl adresa"</string>
+ <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite mirni i potražite sklonište u okolini."</string>
+ <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se sklonite iz priobalnih regiona i oblasti pored reka na neko bezbednije mesto, na primer, na neko uzvišenje."</string>
+ <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni i potražite sklonište u okolini."</string>
+ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testiranje poruka u hitnim slučajevima"</string>
<string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
+ <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kartica nije dozvoljena"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kartica nije podešena"</string>
+ <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
+ <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index d12a104..2702b13 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -91,17 +91,16 @@
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Налады ідэнтыфікатару АВН па змаўчанні: не абмяжавана. Наступны выклік: не абмежавана"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Служба не прадастаўляецца."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"Вы не можаце змяніць налады ідэнтыфікатара абанента, якi тэлефануе."</string>
- <string name="RestrictedOnData" msgid="8653794784690065540">"Служба дадзеных блакуецца."</string>
- <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Аварыйная служба блакуецца."</string>
- <string name="RestrictedOnNormal" msgid="4953867011389750673">"Галасавая служба заблакаваная."</string>
- <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Усе галасавыя службы заблакаваны."</string>
- <string name="RestrictedOnSms" msgid="8314352327461638897">"Служба SMS заблакаваная."</string>
- <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Службы перадачы голаса/дадзеных заблакаваны."</string>
- <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Службы перадачы голаса і SMS заблакаваныя."</string>
- <string name="RestrictedOnAll" msgid="5643028264466092821">"Усе службы перадачы дадзеных, галасавыя і SMS-службы заблакаваны."</string>
+ <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Няма сэрвісу перадачы даных"</string>
+ <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Няма сэрвісу экстранных выклікаў"</string>
+ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Няма сэрвісу галасавых выклікаў"</string>
+ <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Няма сэрвісу галасавых / экстранных выклікаў"</string>
+ <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Ваш аператар часова прыпыніў працу сэрвісу перадачы даных у гэтым месцы"</string>
+ <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Ваш аператар часова прыпыніў працу сэрвісу экстранных выклікаў у гэтым месцы"</string>
+ <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Ваш аператар часова прыпыніў працу сэрвісу галасавых выклікаў у гэтым месцы"</string>
+ <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Ваш аператар часова прыпыніў працу сэрвісу галасавых і экстранных выклікаў у гэтым месцы"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Немагчыма падключыцца да сеткі"</string>
- <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
- <skip />
+ <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Каб палепшыць якасць прыёму, паспрабуйце змяніць тып, выбраны ў меню \"Сістэма > Сетка і інтэрнэт > Мабільныя сеткі > Прыярытэтны тып сеткі\"."</string>
<string name="peerTtyModeFull" msgid="6165351790010341421">"Аднарангавая прылада запытала рэжым TTY FULL"</string>
<string name="peerTtyModeHco" msgid="5728602160669216784">"Аднарангавая прылада запытала рэжым TTY НСО"</string>
<string name="peerTtyModeVco" msgid="1742404978686538049">"Аднарангавая прылада запытала рэжым TTY VCO"</string>
@@ -141,8 +140,7 @@
</string-array>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Выкл."</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Прыярытэт Wi-Fi"</string>
- <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
- <skip />
+ <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Прыярытэт мабільнай сеткі"</string>
<string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Толькі Wi-Fi"</string>
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -182,18 +180,16 @@
<item quantity="other">Усталяваны цэнтры сертыфікацыі</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Невядомая трэцяя асоба"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Адміністратар вашага працоўнага профілю"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Адміністратар вашага працоўнага профілю"</string>
<string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5005572078641980632">"Рабочы профіль выдалены"</string>
- <string name="work_profile_deleted_description" msgid="6305147513054341102">"Рабочы профіль выдалены з-за адсутнасці праграмы адміністравання."</string>
- <string name="work_profile_deleted_details" msgid="226615743462361248">"Праграма для адміністравання рабочага профілю адсутнічае або пашкоджана. У выніку гэтага ваш рабочы профіль і звязаныя з ім даныя былі выдаленыя. Звярніцеся па дапамогу да адміністратара."</string>
- <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Ваш працоўны профіль больш не даступны на гэтай прыладзе."</string>
- <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
- <skip />
- <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
- <skip />
+ <string name="work_profile_deleted_description" msgid="1100529432509639864">"Працоўны профіль выдалены з-за адсутнасці праграмы адміністратара"</string>
+ <string name="work_profile_deleted_details" msgid="6307630639269092360">"Праграма адміністратара для працоўнага профілю адсутнічае або пашкоджана. У выніку гэтага ваш працоўны профіль і звязаныя з ім даныя былі выдалены. Звярніцеся па дапамогу да адміністратара."</string>
+ <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Ваш працоўны профіль больш не даступны на гэтай прыладзе"</string>
+ <string name="network_logging_notification_title" msgid="6399790108123704477">"Прылада знаходзіцца пад кіраваннем"</string>
+ <string name="network_logging_notification_text" msgid="7930089249949354026">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string>
<string name="factory_reset_warning" msgid="5423253125642394387">"Даныя вашай прылады будуць сцерты"</string>
- <string name="factory_reset_message" msgid="4905025204141900666">"Праграма для адміністравання не можа быць выкарыстана, таму што ў яе адсутнічаюць кампаненты або яна пашкоджана. Зараз даныя вашай прылады будуць сцерты. Звярніцеся па дапамогу да адміністратара."</string>
+ <string name="factory_reset_message" msgid="7972496262232832457">"Немагчыма выкарыстоўваць праграму адміністратара. Зараз звесткі на вашай прыладзе будуць выдалены.\n\nКалі ў вас ёсць пытанні, звярніцеся да адміністратара вашай арганізацыі."</string>
<string name="me" msgid="6545696007631404292">"Я"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Параметры планшэта"</string>
<string name="power_dialog" product="tv" msgid="6153888706430556356">"Параметры ТБ"</string>
@@ -416,8 +412,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дазваляе прыкладанням атрымлiваць доступ да функцый тэлефона на прыладзе. Дзякуючы гэтаму дазволу прыкладанне можа вызначаць iдэнтыфiкатары нумару тэлефона i прылады, незалежна ад таго, цi актыўны выклiк, i аддалены нумар, на якi робiцца выклiк."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"перанакіраванне выклікаў праз сістэму"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дазваляе праграме перанакіроўваць выклікі праз сістэму ў мэтах паляпшэння выклікаў."</string>
- <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"чытаць нумар тэлефона"</string>
- <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Праграма зможа атрымліваць доступ да тэлефоннага нумара прылады."</string>
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"счытваць нумары тэлефонаў"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Дазваляе праграме атрымліваць доступ да нумароў тэлефонаў на прыладзе."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"прадухіліць планшэт ад пераходу ў рэжым сну"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"прадухіленне пераходу тэлевізара ў рэжым сну"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"забараняць тэлефону пераходзіць ў рэжым сну"</string>
@@ -557,7 +553,7 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дазваляе праграме чытаць і выконваць запіс у канфігурацыю рэжыму «Не турбаваць»."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Кіраваць даўжынёй і сімваламі, дазволенымі пры ўводзе пароляў і PIN-кодаў блакіроўкі экрана."</string>
- <string name="policylab_watchLogin" msgid="914130646942199503">"Сачыць за спробамі разблакоўкі экрана"</string>
+ <string name="policylab_watchLogin" msgid="5091404125971980158">"Сачыць за спробамі разблакіроўкі экрана"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць планшэт або сціраць усе дадзеныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Сачыць за колькасцю няправільна набраных пароляў падчас разблакіроўкі экрана і блакіраваць тэлевізар або сціраць усе даныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць тяэлефон або сціраць усе дадзеныя на ім, калі набрана занадта шмат няправільных пароляў."</string>
@@ -1010,8 +1006,7 @@
<string name="selectTextMode" msgid="1018691815143165326">"Выбраць тэкст"</string>
<string name="undo" msgid="7905788502491742328">"Адрабіць"</string>
<string name="redo" msgid="7759464876566803888">"Узнавіць"</string>
- <!-- no translation found for autofill (3035779615680565188) -->
- <skip />
+ <string name="autofill" msgid="3035779615680565188">"Аўтазапаўненне"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Вылучэнне тэксту"</string>
<string name="addToDictionary" msgid="4352161534510057874">"Дадаць у слоўнік"</string>
<string name="deleteText" msgid="6979668428458199034">"Выдалiць"</string>
@@ -1143,7 +1138,13 @@
<string name="network_switch_metered" msgid="4671730921726992671">"Выкананы пераход да <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
<string name="network_switch_metered_detail" msgid="5325661434777870353">"Прылада выкарыстоўвае <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, калі ў <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма доступу да інтэрнэту. Можа спаганяцца дадатковая плата."</string>
<string name="network_switch_metered_toast" msgid="5779283181685974304">"Выкананы пераход з <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> да <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+ <string-array name="network_switch_type_name">
+ <item msgid="3979506840912951943">"мабільная перадача даных"</item>
+ <item msgid="75483255295529161">"Wi-Fi"</item>
+ <item msgid="6862614801537202646">"Bluetooth"</item>
+ <item msgid="5447331121797802871">"Ethernet"</item>
+ <item msgid="8257233890381651999">"VPN"</item>
+ </string-array>
<string name="network_switch_type_name_unknown" msgid="4552612897806660656">"невядомы тып сеткі"</string>
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Немагчыма падключыцца да Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" дрэннае падключэнне да Інтэрнэту."</string>
@@ -1213,7 +1214,7 @@
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Стварэнне справаздачы пра памылку…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Падзяліцца справаздачай пра памылку?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Перадача справаздачы пра памылку..."</string>
- <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ІТ-адміністратар запытаў справаздачу пра памылку для яе ліквідацыі на гэтай прыладзе. Можа адбыцца абагуленне праграм і даных."</string>
+ <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Ваш адміністратар запытаў справаздачу пра памылку для яе ліквідацыі на гэтай прыладзе. Звесткі праграм і даныя могуць быць абагулены."</string>
<string name="share_remote_bugreport_action" msgid="6249476773913384948">"АБАГУЛІЦЬ"</string>
<string name="decline_remote_bugreport_action" msgid="6230987241608770062">"АДХІЛІЦЬ"</string>
<string name="select_input_method" msgid="8547250819326693584">"Змяніць клавіятуру"</string>
@@ -1224,7 +1225,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> паказваецца паверх іншых праграм"</string>
- <string name="alert_windows_notification_title" msgid="4532185840598192445">"<xliff:g id="NAME">%s</xliff:g> паказв. паверх інш. праграм."</string>
+ <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="3367294525884949878">"АДКЛЮЧЫЦЬ"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Падрыхтоўка <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1401,8 +1402,7 @@
<string name="data_usage_warning_body" msgid="6660692274311972007">"Прагляд выкарыстання і налад."</string>
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Дасягнуты ліміт трафіку 2G-3G"</string>
<string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Дасягнуты ліміт трафіку 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
- <skip />
+ <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Дасягн. ліміт маб. перад. даных"</string>
<string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Дасягн. ліміт перад. даных Wi-Fi"</string>
<string name="data_usage_limit_body" msgid="291731708279614081">"Перад.даных спын. да канца цыкла"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Перавышаны ліміт 2G-3G"</string>
@@ -1501,18 +1501,21 @@
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Выдалiць"</string>
<string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Павялiчыць гук вышэй рэкамендаванага ўзроўню?\n\nДоўгае праслухоўванне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
- <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Камбінацыя хуткага доступу для спецыяльных магчымасцей АКТЫВАВАНА"</string>
- <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Уключайце ці адключайце <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утрымліваючы абедзве кнопкі рэгулявання гучнасці націснутымі на працягу 3 секунд.\n\nВы можаце змяніць сэрвіс у меню \"Налады > Спецыяльныя магчымасці\"."</string>
- <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Дэактываваць камбінацыю хуткага доступу"</string>
- <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Пакінуць актываванай"</string>
+ <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Выкарыстоўваць камбінацыю хуткага доступу для спецыяльных магчымасцей?"</string>
+ <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Калі камбінацыя хуткага доступу ўключана, вы можаце націснуць абедзве кнопкі гучнасці і ўтрымліваць іх 3 секунды, каб уключыць функцыю спецыяльных магчымасцей.\n\n Бягучая функцыя спецыяльных магчымасцей:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Вы можаце змяніць гэту функцыю ў меню \"Налады > Спецыяльныя магчымасці\"."</string>
+ <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Дэактываваць камбінацыю хуткага доступу"</string>
+ <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
<string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў уключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
<string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў адключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
+ <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберыце функцыю для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
+ <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Каб змяняць функцыі, краніце і ўтрымлівайце кнопку \"Спецыяльныя магчымасці\"."</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Павелічэнне"</string>
<string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="2871009331809089783">"Пераход да <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> выходзіць з сістэмы…"</string>
<string name="owner_name" msgid="2716755460376028154">"Уладальнік"</string>
<string name="error_message_title" msgid="4510373083082500195">"Памылка"</string>
- <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ваш адміністратар не дазваляе гэту змену"</string>
+ <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Ваш адміністратар не дазваляе гэту змену"</string>
<string name="app_not_found" msgid="3429141853498927379">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
<string name="revoke" msgid="5404479185228271586">"Ануляваць"</string>
<string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1604,7 +1607,7 @@
<string name="reason_service_unavailable" msgid="7824008732243903268">"Служба друку не ўключана"</string>
<string name="print_service_installed_title" msgid="2246317169444081628">"Усталявана служба <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="print_service_installed_message" msgid="5897362931070459152">"Краніце, каб уключыць"</string>
- <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Увядзіце PIN-код адміністратара"</string>
+ <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Увядзіце PIN-код адміністратара"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Увядзіце PIN-код"</string>
<string name="restr_pin_incorrect" msgid="8571512003955077924">"Няправільны"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Бягучы PIN-код"</string>
@@ -1634,16 +1637,16 @@
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (праца)"</string>
<string name="managed_profile_label_badge_2" msgid="5048136430082124036">"Другая праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="2808305070321719040">"Трэцяя праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="lock_to_app_toast" msgid="7693684144593484">"Каб адмацаваць гэты экран, дакраніцеся і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\"."</string>
- <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Праграма замацавана: адмацаванне на гэтай прыладзе не дапускаецца."</string>
+ <string name="lock_to_app_toast" msgid="6820571533009838261">"Каб адмацаваць гэты экран, краніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\""</string>
+ <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Гэту праграму нельга адмацаваць"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Экран замацаваны"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Экран адмацаваны"</string>
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Запытваць PIN-код перад адмацаваннем"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запытваць пароль перад адмацаваннем"</string>
- <string name="package_installed_device_owner" msgid="8420696545959087545">"Усталявана вашым адміністратарам"</string>
- <string name="package_updated_device_owner" msgid="8856631322440187071">"Абноўлена вашым адміністратарам"</string>
- <string name="package_deleted_device_owner" msgid="7650577387493101353">"Выдалена вашым адміністратарам"</string>
+ <string name="package_installed_device_owner" msgid="6875717669960212648">"Усталяваны вашым адміністратарам"</string>
+ <string name="package_updated_device_owner" msgid="1847154566357862089">"Абноўлены вашым адміністратарам"</string>
+ <string name="package_deleted_device_owner" msgid="2307122077550236438">"Выдалены вашым адміністратарам"</string>
<string name="battery_saver_description" msgid="1960431123816253034">"Каб падоўжыць час працы акумулятара, у рэжыме эканоміі зараду памяншаецца прадукцыйнасць вашай прылады, абмяжоўваецца выкарыстанне вібрацыі, службаў вызначэння месцазнаходжання і большасці задач фонавай перадачы даных. Электронная пошта, абмен паведамленнямі і іншыя праграмы, якія выкарыстоўваюць сінхранізацыю, могуць не абнаўляцца, пакуль вы іх не адкрыеце.\n\nРэжым эканоміі зараду адключаецца аўтаматычна, калі прылада зараджаецца."</string>
<string name="data_saver_description" msgid="6015391409098303235">"Каб паменшыць выкарыстанне даных, Эканомія трафіку не дазваляе некаторым праграмам адпраўляць ці атрымліваць даныя ў фонавым рэжыме. Праграма, якую вы зараз выкарыстоўваеце, можа атрымліваць доступ да даных, але можа рабіць гэта радзей. Гэта можа азначаць, напрыклад, што відарысы не паказваюцца, пакуль вы не дакраняцеся да іх."</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"Уключыць Эканомію трафіка?"</string>
@@ -1746,8 +1749,8 @@
<string name="language_picker_section_all" msgid="3097279199511617537">"Усе мовы"</string>
<string name="region_picker_section_all" msgid="8966316787153001779">"Усе рэгіёны"</string>
<string name="locale_search_menu" msgid="2560710726687249178">"Шукаць"</string>
- <string name="work_mode_off_title" msgid="8954725060677558855">"Рэжым працы АДКЛЮЧАНЫ"</string>
- <string name="work_mode_off_message" msgid="3286169091278094476">"Дазволіць функцыянаванне працоўнага профілю, у тым ліку праграм, фонавай сінхранізацыі і звязаных з імі функцый."</string>
+ <string name="work_mode_off_title" msgid="2615362773958585967">"Уключыць працоўны рэжым?"</string>
+ <string name="work_mode_off_message" msgid="2961559609199223594">"Гэта прывядзе да ўключэння вашага працоўнага профілю, у тым ліку праграм, фонавай сінхранізацыі і звязаных з імі функцый"</string>
<string name="work_mode_turn_on" msgid="2062544985670564875">"Уключыць"</string>
<string name="new_sms_notification_title" msgid="8442817549127555977">"У вас ёсць новыя паведамленні"</string>
<string name="new_sms_notification_content" msgid="7002938807812083463">"Праглядзець праз праграму для SMS"</string>
@@ -1790,22 +1793,26 @@
<string name="time_picker_prompt_label" msgid="7588093983899966783">"Увядзіце час"</string>
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Пераключыцца на рэжым тэксту пры ўводзе часу."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Пераключыцца на рэжым гадзінніка пры ўводзе часу."</string>
- <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
- <skip />
+ <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Параметры аўтазапаўнення"</string>
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Для гэтага змесціва аўтазапаўненне немагчымае"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Захаваць у <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Захаваць наступнае: <xliff:g id="TYPE">%1$s</xliff:g> у <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Захаваць <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> у <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Захаваць <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> у <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Захаваць"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Не, дзякуй"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"пароль"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"адрас"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"крэдытная картка"</string>
- <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"карыстальнік"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"адрас электроннай пошты"</string>
+ <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Заставайцеся спакойнымі і пашукайце прытулак паблізу."</string>
+ <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Неадкладна эвакуіруйцеся з прыбярэжных раёнаў у больш бяспечнае месца, напрыклад на ўзвышша."</string>
+ <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Заставайцеся спакойнымі і пашукайце прытулак паблізу."</string>
+ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Праверка экстранных паведамленняў"</string>
<string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
+ <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-карта не дапускаецца"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-карты няма"</string>
+ <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-карта не дапускаецца"</string>
+ <string name="mmcc_illegal_me" msgid="4438696681169345015">"Тэлефон не дапускаецца"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 2a77fac..ed3fb22 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Превключете към режима за въвеждане на текст, за да въведете часа."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Превключете към режима за часовник, за да въведете часа."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Опции за автоматично попълване"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Съдържанието не може да бъде попълнено автоматично"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Да се запази ли в/ъв „<xliff:g id="LABEL">%1$s</xliff:g>“?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> да се запази ли в/ъв „<xliff:g id="LABEL">%2$s</xliff:g>“?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Запазване"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Не, благодаря"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"Паролата"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"Адресът"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"Кредитната карта"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"потребителско име"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"имейл адрес"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Запазете спокойствие и потърсете убежище в района."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Евакуирайте се незабавно от крайбрежните и крайречните региони на по-безопасно място – например такова с по-високо надморско равнище."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Запазете спокойствие и потърсете убежище в района."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 3a5fdec..83db42c 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1733,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"সময় ইনপুট দেওয়ার জন্য পাঠ্য ইনপুট মোডে যান।"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"সময় ইনপুট দেওয়ার জন্য ঘড়ি মোডে যান।"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"আপনাআপনি পূরণ করার বিকল্পগুলি"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"বিষয়বস্তুগুলি অটো-ফিল করা যাবে না"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> এ সংরক্ষণ করবেন?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="LABEL">%2$s</xliff:g> এ <xliff:g id="TYPE">%1$s</xliff:g> সংরক্ষণ করবেন?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"সংরক্ষণ করুন"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"না থাক"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"পাসওয়ার্ড"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ঠিকানা"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ক্রেডিট কার্ড"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ইউজারনেম"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ইমেল ঠিকানা"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"শান্ত থাকুন, আশেপাশে আশ্রয় খুঁজুন।"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"উপকূলবর্তী এবং নদীর পাশের অঞ্চল থেকে অবিলম্বে উঁচু কোনো জায়গার দিকে যান।"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"শান্ত থাকুন, আশেপাশে আশ্রয় খুঁজুন।"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 92294dc..6b8fa78 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -90,17 +90,16 @@
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Prikaz ID-a pozivaoca u zadanim postavkama nije zabranjen. Sljedeći poziv: nije zabranjen"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Uslugu nije moguće koristiti."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete promijeniti postavke ID-a pozivaoca."</string>
- <string name="RestrictedOnData" msgid="8653794784690065540">"Usluga prijenosa podataka je blokirana."</string>
- <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Hitni pozivi su blokirani."</string>
- <string name="RestrictedOnNormal" msgid="4953867011389750673">"Govorne usluge su blokirane."</string>
- <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Sve govorne usluge su blokirane."</string>
- <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS usluga je blokirana."</string>
- <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Blokirane su govorne usluge i usluge prijenosa podataka."</string>
- <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Blokirane su govorne/SMS usluge."</string>
- <string name="RestrictedOnAll" msgid="5643028264466092821">"Blokirane su sve govorne i SMS usluge te usluge prijenosa podataka."</string>
+ <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nema usluge prijenosa mobilnih podataka"</string>
+ <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nema usluge za hitne slučajeve"</string>
+ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nema usluge govornih poziva"</string>
+ <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema govornih/hitnih usluga"</string>
+ <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Vaš operater je privremeno obustavio uslugu prijenosa mobilnih podataka na ovoj lokaciji"</string>
+ <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Vaš operater je privremeno obustavio hite pozive na ovoj lokaciji"</string>
+ <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Vaš operater je privremeno obustavio govorne pozive na ovoj lokaciji"</string>
+ <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Vaš operater je na ovoj lokaciji privremeno obustavio govorne i hitne pozive."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nije moguće dosegnuti mrežu"</string>
- <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
- <skip />
+ <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Za poboljšanje prijema, pokušajte promijeniti tip odabran u meniju Sistem > Mreža i internet > Mobilne mreže > Preferirani tip mreže."</string>
<string name="peerTtyModeFull" msgid="6165351790010341421">"Ravnopravni uređaj zatražio TTY PUNI način rada"</string>
<string name="peerTtyModeHco" msgid="5728602160669216784">"Ravnopravni uređaj zatražio TTY HCO način rada"</string>
<string name="peerTtyModeVco" msgid="1742404978686538049">"Ravnopravni uređaj zatražio TTY VCO način rada"</string>
@@ -140,8 +139,7 @@
</string-array>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
- <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
- <skip />
+ <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferira se mobilna mreža"</string>
<string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđen"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -180,18 +178,16 @@
<item quantity="other">Instalirane su ustanove za izdavanje certifikata</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od nepoznate treće strane"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"od strane administratora vašeg profila za posao"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Administrator vašeg radnog profila"</string>
<string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5005572078641980632">"Poslovni profil je obrisan"</string>
- <string name="work_profile_deleted_description" msgid="6305147513054341102">"Poslovni profil je obrisan jer nedostaje aplikacija administratora."</string>
- <string name="work_profile_deleted_details" msgid="226615743462361248">"Aplikacija administratora za poslovni profil nedostaje ili je neispravna. Zbog toga su vaš poslovni profil i vezani podaci obrisani. Za pomoć se obratite administratoru."</string>
- <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Profil za posao više nije dostupan na ovom uređaju."</string>
- <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
- <skip />
- <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
- <skip />
+ <string name="work_profile_deleted_description" msgid="1100529432509639864">"Radni profil je izbrisan jer nedostaje aplikacija administratora"</string>
+ <string name="work_profile_deleted_details" msgid="6307630639269092360">"Nedostaje aplikacija administratora za radni profil ili je neispravna. Zbog toga su vaš radni profil i povezani podaci izbrisani. Obratite administratoru za pomoć."</string>
+ <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Radni profil više nije dostupan na ovom uređaju"</string>
+ <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja."</string>
+ <string name="network_logging_notification_text" msgid="7930089249949354026">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string>
<string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti izbrisan"</string>
- <string name="factory_reset_message" msgid="4905025204141900666">"Aplikaciji administratora nedostaju komponente ili je neispravna, i ne može se koristiti. Vaš uređaj će sada biti izbrisan. Za pomoć se obratite administratoru."</string>
+ <string name="factory_reset_message" msgid="7972496262232832457">"Nije moguće koristiti aplikaciju administratora. Potpuno će se izbrisati podaci na vašem uređaju.\n\nAko imate pitanja, obratite se administratoru vaše organizacije."</string>
<string name="me" msgid="6545696007631404292">"Ja"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije tableta"</string>
<string name="power_dialog" product="tv" msgid="6153888706430556356">"Opcije za TV"</string>
@@ -413,8 +409,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Omogućava aplikaciji pristup telefonskim funkcijama uređaja. Ova dozvola omogućava aplikaciji određivanje telefonskog i identifikacionog broja uređaja, bez obzira da li je poziv aktivan i da li je uspostavljena veza sa pozivanim brojem."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"usmjeravanje poziva preko sistema"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dopušta aplikaciji da pozive usmjeri preko sistema radi poboljšanja iskustva pozivanja."</string>
- <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"čitanje telefonskog broja"</string>
- <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Dopušta aplikaciji pristup telefonskom broju telefona."</string>
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje telefonskih brojeva"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Dozvoljava aplikaciji pristup telefonskim brojevima uređaja."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"sprečavanje tableta da uđe u režim mirovanja"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"spriječi ulazak TV-a u režim mirovanja"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečavanje telefona da uđe u režim mirovanja"</string>
@@ -554,7 +550,7 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućava aplikaciji da čita i upisuje konfiguraciju opcije Ne ometaj."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Postavljanje pravila za lozinke"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN kodovima."</string>
- <string name="policylab_watchLogin" msgid="914130646942199503">"Prati pokušaje otključavanja ekrana"</string>
+ <string name="policylab_watchLogin" msgid="5091404125971980158">"Prati pokušaje otključavanja ekrana"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Prati broj pogrešno unijetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše sve podatke s njega ukoliko se previše puta unese pogrešna lozinka."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Prati koliko puta je lozinka neispravno otkucana prilikom otključavanja ekrana i zaključaj TV ili izbriši sve podatke s TV-a ako se lozinka neispravno ukuca previše puta."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Prati broj pogrešno unesenih lozinki prilikom otključavanja ekrana i zaključava telefon ili briše sve podatke s telefona ukoliko se previše puta unese pogrešna lozinka."</string>
@@ -990,8 +986,7 @@
<string name="selectTextMode" msgid="1018691815143165326">"Odaberi tekst"</string>
<string name="undo" msgid="7905788502491742328">"Vrati"</string>
<string name="redo" msgid="7759464876566803888">"Ponovo uradi"</string>
- <!-- no translation found for autofill (3035779615680565188) -->
- <skip />
+ <string name="autofill" msgid="3035779615680565188">"Automatsko popunjavanje"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Odabir teksta"</string>
<string name="addToDictionary" msgid="4352161534510057874">"Dodaj u rječnik"</string>
<string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
@@ -1125,7 +1120,13 @@
<string name="network_switch_metered" msgid="4671730921726992671">"Prebačeno na: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
<string name="network_switch_metered_detail" msgid="5325661434777870353">"Kada na uređaju <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, koristi se <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata usluge."</string>
<string name="network_switch_metered_toast" msgid="5779283181685974304">"Prebačeno iz mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> u <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mrežu"</string>
- <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+ <string-array name="network_switch_type_name">
+ <item msgid="3979506840912951943">"mobilni podaci"</item>
+ <item msgid="75483255295529161">"Wi-Fi"</item>
+ <item msgid="6862614801537202646">"Bluetooth"</item>
+ <item msgid="5447331121797802871">"Ethernet"</item>
+ <item msgid="8257233890381651999">"VPN"</item>
+ </string-array>
<string name="network_switch_type_name_unknown" msgid="4552612897806660656">"nepoznata vrsta mreže"</string>
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Problem prilikom spajanja na Wi-Fi mrežu"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internet vezu."</string>
@@ -1198,7 +1199,7 @@
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvještaja o grešci..."</string>
- <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Vaš IT administrator je zatražio izvještaj o grešci kako bi pomogao u rješavanju problema ovog uređaja. Aplikacije i podaci se mogu dijeliti."</string>
+ <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Vaš administrator je zatražio izvještaj o greškama kako bi pomogao u rješavanju problema ovog uređaja. Moguće je dijeljenje aplikacija i podataka."</string>
<string name="share_remote_bugreport_action" msgid="6249476773913384948">"PODIJELI"</string>
<string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBACI"</string>
<string name="select_input_method" msgid="8547250819326693584">"Promijeni tastaturu"</string>
@@ -1209,7 +1210,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva ostale aplikacije"</string>
- <string name="alert_windows_notification_title" msgid="4532185840598192445">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva ostale aplikacije."</string>
+ <string name="alert_windows_notification_title" msgid="3697657294867638947">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva druge apl."</string>
<string name="alert_windows_notification_message" msgid="8917232109522912560">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string>
<string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Priprema se <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1385,8 +1386,7 @@
<string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za prikaz upotrebe i postavki."</string>
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Dostignut limit za 2G-3G podatke"</string>
<string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Dostignut limit za 4G podatke"</string>
- <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
- <skip />
+ <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dostignut limit za mob. podatke"</string>
<string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Dostignut limit Wi-Fi podataka"</string>
<string name="data_usage_limit_body" msgid="291731708279614081">"Podaci pauz. za ostatak ciklusa"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Premašeni 2G-3G podaci"</string>
@@ -1486,18 +1486,21 @@
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
<string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
- <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Prečica za pristupačnost je UKLJUČENA"</string>
- <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Držite oba dugmeta za podešavanje jačine zvuka 3 sekunde da uključite ili isključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>.\n\nUslugu možete promijeniti ako odete u Postavke > Pristupačnost."</string>
- <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Isključi prečicu"</string>
- <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Ostavi uključeno"</string>
+ <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Želite li koristiti Prečicu za pristupačnost?"</string>
+ <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Kada je prečica uključena, pritiskom na oba dugmeta za podešavanje jačine zvuka u trajanju od 3 sekunde pokrenut će se funkcija za pristupačnost.\n\n Trenutna funkcija za pristupačnost je:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkciju možete promijeniti ako odete u Postavke > Pristupačnost."</string>
+ <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Isključi prečicu"</string>
+ <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Koristi prečicu"</string>
<string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
+ <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da promijenite funkcije, dodirnite i držite dugme Pristupačnost."</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
<string name="user_switched" msgid="3768006783166984410">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="8939524935808875155">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
<string name="error_message_title" msgid="4510373083082500195">"Greška"</string>
- <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Promjenu ne dopušta vaš administrator"</string>
+ <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Vaš administrator ne dozvoljava ovu promjenu"</string>
<string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija koja će upravljati ovom akcijom."</string>
<string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
<string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1589,7 +1592,7 @@
<string name="reason_service_unavailable" msgid="7824008732243903268">"Usluga štampanja nije omogućena."</string>
<string name="print_service_installed_title" msgid="2246317169444081628">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
<string name="print_service_installed_message" msgid="5897362931070459152">"Dodirnite da omogućite"</string>
- <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite administratorski PIN"</string>
+ <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Upišite PIN kôd administratora"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
<string name="restr_pin_incorrect" msgid="8571512003955077924">"Netačno"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutni PIN"</string>
@@ -1618,16 +1621,16 @@
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="lock_to_app_toast" msgid="7693684144593484">"Da biste otkačili ovaj ekran, dodirnite i držite dugme Nazad i Pregled."</string>
- <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je prikačena. Na ovom uređaju nije dozvoljeno otkačivanje."</string>
+ <string name="lock_to_app_toast" msgid="6820571533009838261">"Da otkačite ovaj ekran, dodirnite i držite dugmad Nazad i Pregled."</string>
+ <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ova aplikacija se ne može otkačiti"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string>
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN prije nego se otkači"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje prije nego se otkači"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku prije nego se otkači"</string>
- <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string>
- <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao administrator"</string>
- <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
+ <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao je vaš administrator"</string>
+ <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je vaš administrator"</string>
+ <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je vaš administrator"</string>
<string name="battery_saver_description" msgid="1960431123816253034">"Da bi se trajanje baterije produžilo, opcija za štednju baterije minimizira rad uređaja i ograničava vibriranje, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu biti ažurirane dok ih ne otvorite.\n\nŠtednja baterije se automatski isključi prilikom punjenja uređaja."</string>
<string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio prijenos podataka, usluga Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali se to može desiti rjeđe. To može značiti, naprimjer, da se slike ne prikazuju sve dok ih ne dodirnete."</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
@@ -1721,8 +1724,8 @@
<string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
<string name="region_picker_section_all" msgid="8966316787153001779">"Sve regije"</string>
<string name="locale_search_menu" msgid="2560710726687249178">"Pretraga"</string>
- <string name="work_mode_off_title" msgid="8954725060677558855">"Radni način rada je ISKLJUČEN"</string>
- <string name="work_mode_off_message" msgid="3286169091278094476">"Omogući radnom profilu da funkcionira, uključujući aplikacije, sinhronizaciju u pozadini i povezane funkcije."</string>
+ <string name="work_mode_off_title" msgid="2615362773958585967">"Želite uključiti radni način?"</string>
+ <string name="work_mode_off_message" msgid="2961559609199223594">"Ovim će se uključiti vaš radni profil, uključujući aplikacije, sinhronizacija u pozadini i povezane funkcije"</string>
<string name="work_mode_turn_on" msgid="2062544985670564875">"Uključi"</string>
<string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
@@ -1765,22 +1768,26 @@
<string name="time_picker_prompt_label" msgid="7588093983899966783">"Upišite vrijeme"</string>
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Prebacite u način unosa teksta za unos vremena."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Prebacite u način rada kao sat za unos vremena."</string>
- <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
- <skip />
+ <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcije za automatsko popunjavanje"</string>
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sadržaje nije moguće automatski popuniti"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Želite li sačuvati u: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Želite li sačuvati stavku <xliff:g id="TYPE">%1$s</xliff:g> u: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Želite li <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> sačuvati u <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Želite li <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> sačuvati u <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Sačuvaj"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"lozinka"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditna kartica"</string>
- <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
- <skip />
- <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"korisničko ime"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adresa e-pošte"</string>
+ <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite smireni i potražite sklonište u blizini."</string>
+ <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se evakuirajte iz priobalnih područja i područja oko rijeka na sigurnije mjesto kao što su viši predjeli."</string>
+ <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite smireni i potražite sklonište u blizini."</string>
+ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test poruka za hitne slučajeve"</string>
<string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
+ <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kartica nije dozvoljena"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kartica nije dodijeljena"</string>
+ <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
+ <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index ada00d2..f0b4a08 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1185,7 +1185,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"S\'està superposant <xliff:g id="NAME">%s</xliff:g> a altres aplicacions"</string>
- <string name="alert_windows_notification_title" msgid="3697657294867638947">"Superposant <xliff:g id="NAME">%s</xliff:g> a altres apps"</string>
+ <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="3367294525884949878">"DESACTIVA"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"S\'està preparant <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Canvia al mode d\'introducció de text per introduir l\'hora."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Canvia al mode de rellotge per introduir l\'hora."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcions d\'emplenament automàtic"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"El contingut no es pot emplenar automàticament"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Vols desar-ho a <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Vols desar la informació del camp <xliff:g id="TYPE">%1$s</xliff:g> a <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Desa"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No, gràcies"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"contrasenya"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adreça"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"targeta de crèdit"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nom d\'usuari"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adreça electrònica"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Mantén la calma i busca refugi a prop."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandona immediatament les regions costaneres i riberenques, i cerca un lloc més segur, com ara un terreny elevat."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma i busca refugi a prop."</string>
@@ -1753,5 +1754,5 @@
<string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM no compatible"</string>
<string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM no proporcionada"</string>
<string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM no compatible"</string>
- <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telèfonno no compatible"</string>
+ <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telèfon no no compatible"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index eab7078..306a393 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1794,19 +1794,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Chcete-li zadat čas, přepněte na režim textu."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Chcete-li zadat čas, přepněte na režim hodin."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Možnosti automatického vyplňování"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Obsah nelze automaticky vyplnit"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Uložit do služby <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Uložit položku <xliff:g id="TYPE">%1$s</xliff:g> do služby <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Uložit"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ne, děkuji"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"heslo"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"platební karta"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"uživatelské jméno"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-mailová adresa"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Zachovejte klid a přesuňte se na bezpečné místo v okolí."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Z pobřežních oblastí a okolí řek se co nejrychleji přesuňte do většího bezpečí (například na výše položené místo)."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachovejte klid a přesuňte se na bezpečné místo v okolí."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e66a146..962a089 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Skift til teksttilstand for at angive klokkeslæt."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Skift til urtilstand for at angive klokkeslæt."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Valgmuligheder for AutoFyld"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Indhold kan ikke udfyldes automatisk"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Skal indholdet gemmes i <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Skal <xliff:g id="TYPE">%1$s</xliff:g> gemmes i <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Gem"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nej tak"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"adgangskode"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresse"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditkort"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"brugernavn"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"mailadresse"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Bevar roen, og søg ly i nærheden."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Forlad omgående kyst- og flodområder, og søg mod et mere sikkert sted, f.eks. et højere terræn."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bevar roen, og søg ly i nærheden."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a0ebdeb..f743f7d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"In den Texteingabemodus wechseln, um die Uhrzeit einzugeben."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"In den Uhrzeitmodus wechseln, um die Uhrzeit einzugeben."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"AutoFill-Optionen"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Inhalte können nicht automatisch ausgefüllt werden"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"In <xliff:g id="LABEL">%1$s</xliff:g> speichern?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> in <xliff:g id="LABEL">%2$s</xliff:g> speichern?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Speichern"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nein danke"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"Passwort"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"Adresse"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"Kreditkarte"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"Nutzername"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"E-Mail-Adresse"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Bleibe ruhig und suche in der Nähe Schutz."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Verlasse so schnell wie möglich Flussufer und Küstengebiete und suche in einer höher gelegenen Umgebung Schutz."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bleibe ruhig und suche in der Nähe Schutz."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 5805f83..ec49827 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Κάντε εναλλαγή στη λειτουργία εισαγωγής κειμένου, για την εισαγωγή της ώρας."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Κάντε εναλλαγή στη λειτουργία ρολογιού, για την εισαγωγή της ώρας."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Επιλογές αυτόματης συμπλήρωσης"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Δεν είναι δυνατή η αυτόματη συμπλήρωση των περιεχομένων"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Αποθήκευση σε <xliff:g id="LABEL">%1$s</xliff:g>;"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Αποθήκευση <xliff:g id="TYPE">%1$s</xliff:g> σε <xliff:g id="LABEL">%2$s</xliff:g>;"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Αποθήκευση"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Όχι, ευχαριστώ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"κωδικός πρόσβασης"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"διεύθυνση"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"πιστωτική κάρτα"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"όνομα χρήστη"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"διεύθυνση email"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Μείνετε ψύχραιμοι και αναζητήστε κάποιο κοντινό καταφύγιο."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Εκκενώστε αμέσως τις παράκτιες περιοχές και τις περιοχές δίπλα σε ποτάμια και μετακινηθείτε σε ένα ασφαλέστερο μέρος, όπως περιοχές με υψόμετρο."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Μείνετε ψύχραιμοι και αναζητήστε κάποιο κοντινό καταφύγιο."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 500754d..0a6a7d5 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1732,19 +1732,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Switch to text input mode for the time input."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Switch to clock mode for the time input."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Auto-fill options"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Contents can’t be auto-filled"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Save to <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Save <xliff:g id="TYPE">%1$s</xliff:g> to <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Save <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> to <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Save <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> to <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Save"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No thanks"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"password"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"address"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"credit card"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"username"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"email address"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Stay calm and seek shelter nearby."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 500754d..0a6a7d5 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1732,19 +1732,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Switch to text input mode for the time input."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Switch to clock mode for the time input."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Auto-fill options"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Contents can’t be auto-filled"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Save to <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Save <xliff:g id="TYPE">%1$s</xliff:g> to <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Save <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> to <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Save <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> to <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Save"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No thanks"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"password"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"address"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"credit card"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"username"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"email address"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Stay calm and seek shelter nearby."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 500754d..0a6a7d5 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1732,19 +1732,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Switch to text input mode for the time input."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Switch to clock mode for the time input."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Auto-fill options"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Contents can’t be auto-filled"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Save to <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Save <xliff:g id="TYPE">%1$s</xliff:g> to <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Save <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> to <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Save <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> to <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Save"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No thanks"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"password"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"address"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"credit card"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"username"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"email address"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Stay calm and seek shelter nearby."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index feccac9..e764a19 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia al modo de entrada de texto para ingresar la hora."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Cambia al modo de reloj para ingresar la hora."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opciones de autocompletar"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"El contenido no puede autocompletarse"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"¿Quieres guardar el contenido en <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"¿Quieres guardar el contenido de <xliff:g id="TYPE">%1$s</xliff:g> en <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Guardar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No, gracias"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"contraseña"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"dirección"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"tarjeta de crédito"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nombre de usuario"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"dirección de correo electrónico"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Mantén la calma y busca un refugio cercano."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacúa inmediatamente las regiones costeras y ribereñas en busca de un lugar seguro, como un terreno elevado."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma y busca un refugio cercano."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f5bb4a0..67c5372 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia al modo de introducción de texto para escribir la hora."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Cambia al modo de reloj para escribir la hora."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opciones de Autocompletar"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"El contenido no se puede autocompletar"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"¿Guardar en <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"¿Guardar <xliff:g id="TYPE">%1$s</xliff:g> en <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Guardar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No, gracias"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"contraseña"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"dirección"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"tarjeta de crédito"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nombre de usuario"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"dirección de correo electrónico"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Mantén la calma y busca refugio en algún lugar cercano."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Aléjate inmediatamente de las zonas costeras y situadas junto a un río para dirigirte hacia un lugar más seguro, por ejemplo, un terreno elevado."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma y busca refugio en algún lugar cercano."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index aa73458..e18f177 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Aktiveerige kellaaja sisestamiseks tekstisisestusrežiim."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Aktiveerige kellaaja sisestamiseks kellarežiim."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Automaatse täitmise valikud"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sisu ei saa automaatselt täita"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Kas salvestada sildiga <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Kas salvestada <xliff:g id="TYPE">%1$s</xliff:g> sildiga <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Salvesta"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Tänan, ei"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"parool"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"aadress"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"krediitkaart"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"kasutajanimi"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-posti aadress"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Jääge rahulikuks ja otsige lähedusest peavarju."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakueeruge ranniku ja jõekallaste piirkondadest viivitamatult ohutusse kohta, näiteks kõrgematesse kohtadesse."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Jääge rahulikuks ja otsige lähedusest peavarju."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index d151045..6e0d929 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -307,7 +307,7 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"birbideratu irteerako deiak"</string>
<string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Irteerako deian markatutako zenbakia ikustea baimentzen die aplikazioei, deia beste zenbaki batera birbideratzeko edo deia bertan behera uzteko aukerarekin."</string>
<string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"erantzun telefono-deiak"</string>
- <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"Sarrerako deiak hartzea baimentzen dio aplikazioari."</string>
+ <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"Sarrerako deiak hartzea baimentzen die aplikazioei."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"jaso testu-mezuak (SMSak)"</string>
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS mezuak jasotzeko eta prozesatzeko baimena ematen die aplikazioei. Horrela, aplikazioak gailura bidalitako mezuak kontrola eta ezaba ditzake zuri erakutsi gabe."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"jaso testu-mezuak (MMSak)"</string>
@@ -405,9 +405,9 @@
<string name="permlab_readPhoneState" msgid="9178228524507610486">"irakurri telefonoaren egoera eta identitatea"</string>
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Gailuaren telefono-eginbideak atzitzeko baimena ematen die aplikazioei. Baimen horrek aplikazioari telefono-zenbakia eta gailu IDak zein diren, deirik aktibo dagoen eta deia zer zenbakirekin konektatuta dagoen zehazteko baimena ematen die aplikazioei."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"bideratu deiak sistemaren bidez"</string>
- <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Deiak sistemaren bidez bideratzea baimentzen dio aplikazioari, deien zerbitzua ahal bezain ona izan dadin."</string>
+ <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Deiak sistemaren bidez bideratzea baimentzen die aplikazioei, deien zerbitzua ahal bezain ona izan dadin."</string>
<string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"irakurri telefono-zenbakiak"</string>
- <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Gailuaren telefono-zenbakiak atzitzea baimentzen dio aplikazioari."</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Gailuaren telefono-zenbakiak atzitzea baimentzen die aplikazioei."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"eragotzi tableta inaktibo ezartzea"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"eragotzi telebista inaktibo geratzea"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"eragotzi telefonoa inaktibo ezartzea"</string>
@@ -1733,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Aldatu testu modura ordua zehazteko."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Aldatu erloju modura ordua zehazteko."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Betetze automatikoaren aukerak"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Ezin dira bete automatikoki eremuak"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> zerbitzuan gorde?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="LABEL">%2$s</xliff:g> zerbitzuan gorde nahi duzu <xliff:g id="TYPE">%1$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Gorde"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ez, eskerrik asko"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"pasahitza"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"helbidea"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditu-txartela"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"erabiltzaile-izena"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"helbide elektronikoa"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ez larritu eta bilatu babesleku bat inguruan."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ebakuatu kostaldeak eta ibaialdeak berehala eta joan toki seguru batera, adibidez, toki garai batera."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ez larritu eta bilatu babesleku bat inguruan."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index edf9bf8..0cec9f9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"برای وارد کردن زمان، به حالت وارد کردن نوشتار تغییر وضعیت دهید."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"برای وارد کردن زمان، به حالت ساعت تغییر وضعیت دهید."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"گزینههای تکمیل خودکار"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"تکمیل خودکار محتوا ممکن نیست"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"در <xliff:g id="LABEL">%1$s</xliff:g> ذخیره شود؟"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> در <xliff:g id="LABEL">%2$s</xliff:g> ذخیره شود؟"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"ذخیره"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"نه سپاسگزارم"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"گذرواژه"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"نشانی"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"کارت اعتباری"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"نام کاربری"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"نشانی رایانامه"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"آرام باشید و پناهگاهی در این اطراف پیدا کنید."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"فوراً مناطق ساحلی و محدوده رودخانه را ترک کنید و به جایی امن، مثل ارتفاعات بروید."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"آرام باشید و پناهگاهی در این اطراف پیدا کنید."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index af73c15..9384ae5 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Vaihda ajan syöttämiseen tekstitilassa."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Vaihda ajan syöttämiseen kellotilassa."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Automaattisen täytön asetukset"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sisältöä ei voi täyttää automaattisesti."</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Tallennetaanko kohteeseen <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Tallennetaanko <xliff:g id="TYPE">%1$s</xliff:g> kohteeseen <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Tallenna"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ei kiitos"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"salasana"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"osoite"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"luottokortti"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"käyttäjänimi"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"sähköpostiosoite"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Pysy rauhallisena ja hakeudu lähimpään suojapaikkaan."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Siirry heti rannikkoalueilta ja jokien varsilta korkeampiin tai muuten turvallisempiin paikkoihin."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Pysy rauhallisena ja hakeudu lähimpään suojapaikkaan."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 1e25181..de4c728 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Passer au mode Entrée de texte pour entrer l\'heure."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Passer au mode Horloge pour entrer l\'heure."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Options de remplissage automatique"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Le contenu ne peut pas être entré automatiquement"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Enregistrer sous <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Enregistrer <xliff:g id="TYPE">%1$s</xliff:g> sous <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Enregistrer"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Non, merci"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"mot de passe"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresse"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"carte de crédit"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nom d\'utilisateur"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adresse de courriel"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Restez calme et cherchez un abri à proximité."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Évacuez immédiatement les zones côtières et les rives des fleuves, et réfugiez-vous dans un endroit plus sécuritaire, comme un terrain surélevé."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Restez calme et cherchez un abri à proximité."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 25bd58a1f..3db6d83 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Passer en mode saisie de texte pour la saisie de l\'heure."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Passer en mode horloge pour la saisie de l\'heure."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Options de saisie automatique"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Le contenu ne peut pas être saisi automatiquement"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Enregistrer dans \"<xliff:g id="LABEL">%1$s</xliff:g>\" ?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Enregistrer \"<xliff:g id="TYPE">%1$s</xliff:g>\" dans \"<xliff:g id="LABEL">%2$s</xliff:g>\" ?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Enregistrer"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Non, merci"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"mot de passe"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresse"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"carte de paiement"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nom d\'utilisateur"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adresse e-mail"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Restez calme et cherchez un abri à proximité."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Évacuez immédiatement les zones côtières et les berges des fleuves, et réfugiez-vous dans un endroit plus sûr, comme un terrain surélevé."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Restez calme et cherchez un abri à proximité."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index a726854..eb220f4 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1186,7 +1186,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Mostrando <xliff:g id="NAME">%s</xliff:g> sobre outras aplicacións"</string>
- <string name="alert_windows_notification_title" msgid="3697657294867638947">"Sobre aplicacións móstrase: <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> móstrase sobre outras aplicacións"</string>
<string name="alert_windows_notification_message" msgid="8917232109522912560">"Se non queres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca para abrir a configuración e desactívaa."</string>
<string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESACTIVAR"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparando a <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1733,19 +1733,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia ao modo de entrada de texto para introducir a hora."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Cambiar ao modo de reloxo para introducir a hora."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcións de autocompletar"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Os contidos non se poden autocompletar"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Queres gardar o contido en: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Queres gardar o contido (<xliff:g id="TYPE">%1$s</xliff:g>) en: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Queres gardar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> en: <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Queres gardar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g> en: <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Gardar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Non, grazas"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"contrasinal"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"enderezo"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"tarxeta de crédito"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nome de usuario"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"enderezo de correo electrónico"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Mantén a calma e busca refuxio cerca."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandona de inmediato rexións costeiras e situadas na beira de ríos para dirixirte a un lugar máis seguro, como un terreo elevado."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén a calma e busca refuxio cerca."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index f3e52e1..6b771fd 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -406,10 +406,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"એપ્લિકેશનને ફોન સુવિધાઓને ઍક્સેસ કરવાની મંજૂરી આપે છે. આ પરવાનગી એપ્લિકેશનને ફોન નંબર અને ઉપકરણ ID, કૉલ સક્રિય છે અને કોઈ કૉલ દ્વારા કનેક્ટ થયેલ રિમોટ નંબર નિર્ધારિત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"સિસ્ટમ મારફતે કૉલ બીજે વાળો"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"કૉલિંગ અનુભવ સુધારવા માટે ઍપ્લિકેશનને સિસ્ટમ મારફતે કૉલ બીજે વાળવાની મંજૂરી આપે છે."</string>
- <!-- no translation found for permlab_readPhoneNumbers (6108163940932852440) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneNumbers (8559488833662272354) -->
- <skip />
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ફોન નંબર વાંચો"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"ઍપ્લિકેશનને ઉપકરણનાં ફોન નંબરને ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ટેબ્લેટને નિષ્ક્રિય થતું અટકાવો"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"ટીવીને નિષ્ક્રિય થતો અટકાવો"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ફોનને નિષ્ક્રિય થતો અટકાવો"</string>
@@ -1188,8 +1186,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનોની ઉપર પ્રદર્શિત થઈ રહ્યું છે"</string>
- <!-- no translation found for alert_windows_notification_title (3697657294867638947) -->
- <skip />
+ <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="3367294525884949878">"બંધ કરો"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> ને તૈયાર કરી રહ્યું છે"</string>
@@ -1740,15 +1737,17 @@
<skip />
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> માં સાચવીએ?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ને <xliff:g id="LABEL">%2$s</xliff:g> માં સાચવીએ?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"સાચવો"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"નહીં આભાર"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"પાસવર્ડ"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"સરનામું"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ક્રેડિટ કાર્ડ"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"વપરાશકર્તાનામ"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ઇમેઇલ સરનામું"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"શાંત રહો અને નજીકમાં આશ્રય લો."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"દરિયાકિનારાના પ્રદેશો તથા નદીકાંઠાના વિસ્તારો ખાલી કરીને તાત્કાલિક સુરક્ષિત ઊંચા સ્થાન પર જાઓ."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"શાંત રહો અને નજીકમાં આશ્રય લો."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 0e94ce3..5e7edfa 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1732,19 +1732,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"समय इनपुट के लिए लेख इनपुट मोड पर जाएं."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"समय इनपुट के लिए घड़ी मोड पर जाएं."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ऑटोमैटिक भरने के विकल्प"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"सामग्रियां ऑटोमैटिक रूप से भरी जा सकती हैं"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> में सहेजें?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> को <xliff:g id="LABEL">%2$s</xliff:g> में सहेजें?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> को <xliff:g id="LABEL">%3$s</xliff:g> में सहेजें?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> को <xliff:g id="LABEL">%4$s</xliff:g> में सहेजें?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"सहेजें"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"नहीं, धन्यवाद"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"पासवर्ड"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"पता"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"क्रेडिट कार्ड"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"उपयोगकर्ता नाम"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ईमेल पता"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"शांत रहें और आस-पास शरण स्थल खोजें."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"तटीय क्षेत्रों और नदी के किनारे वाले क्षेत्रों को जल्द से जल्द खाली करके किसी सुरक्षित ऊंची जगह पर चले जाएं."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शांत रहें और आस-पास आश्रय खोजें."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 7ed7794..d95f8c8 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1763,19 +1763,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Prijeđite na način unosa teksta da biste unijeli vrijeme."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Prijeđite na način rada sata da biste unijeli vrijeme."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcije automatskog popunjavanja"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sadržaj se ne može automatski popuniti"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Želi te li to spremiti u aplikaciju <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Želite li spremiti <xliff:g id="TYPE">%1$s</xliff:g> u aplikaciju <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Želite li spremiti <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> u <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Želite li spremiti <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> u <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Spremi"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"zaporku"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresu"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditnu karticu"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"korisničko ime"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-adresa"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite mirni i potražite sklonište u blizini."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se evakuirajte s obalnih područja i područja uz rijeku na sigurnije mjesto, primjerice povišeno područje."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni i potražite sklonište u blizini."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 8ca82d3..822f740 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Időbevitelhez váltson szövegbeviteli módba."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Időbevitelhez váltson óramódba."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Az automatikus kitöltés beállítási lehetőségei"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"A tartalmakat nem lehet automatikusan kitölteni"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Menti ide: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> mentése ide: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Mentés"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nem, köszönöm"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"jelszó"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"cím"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"hitelkártya"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"felhasználónév"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-mail-cím"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Őrizze meg nyugalmát, és keressen menedéket a közelben."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Azonnal meneküljön biztonságosabb helyre a tengerparti, illetve folyóparti területekről, például valamilyen magaslatra."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Őrizze meg nyugalmát, és keressen menedéket a közelben."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index b97bb1b..7a91c68 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Ժամը մուտքագրելու համար միացրեք տեքստի մուտքագրման ռեժիմը:"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Ժամը մուտքագրելու համար միացրեք ժամացույցի ռեժիմը:"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Ինքնալրացման ընտրանքները"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Բովանդակության ինքնալրացումը հնարավոր չէ"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Պահե՞լ <xliff:g id="LABEL">%1$s</xliff:g>-ում։"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Պահե՞լ <xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="LABEL">%2$s</xliff:g>-ում։"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Պահել"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ոչ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"գաղտնաբառ"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"հասցե"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"վարկային քարտ"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"օգտանուն"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"էլփոստի հասցե"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Պահպանեք հանգստությունը և մոտակայքում ապաստարան փնտրեք:"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ափամերձ և գետափնյա տարածքներից անմիջապես էվակուացվեք դեպի ավելի ապահով վայրեր (օրինակ՝ բարձրադիր գոտիներ):"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Պահպանեք հանգստությունը և մոտակայքում ապաստարան փնտրեք:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 62c1703..cd4e63e 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1732,19 +1732,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Beralih ke mode masukan teks untuk masukan waktu."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Beralih ke mode jam untuk masukan waktu."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opsi Isiotomatis"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Konten tidak dapat diisi otomatis"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Simpan ke <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Simpan <xliff:g id="TYPE">%1$s</xliff:g> ke <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Simpan <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ke <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Simpan <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ke <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Simpan"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Lain kali"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"sandi"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"alamat"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kartu kredit"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nama pengguna"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"alamat email"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Tetap tenang dan cari tempat berlindung terdekat."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuasi segera dari daerah pesisir dan area tepi sungai ke tempat yang lebih aman seperti dataran tinggi."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tetap tenang dan cari tempat berlindung terdekat."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index b5acbec..d87725e 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1733,19 +1733,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Skipta yfir í textastillingu til að færa inn tíma."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Skipta yfir í klukkustillingu til að færa inn tíma."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Valkostir sjálfvirkrar útfyllingar"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Ekki er hægt að fylla innihald út sjálfkrafa"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Vista í <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Vista <xliff:g id="TYPE">%1$s</xliff:g> í <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Vista <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> á <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Vista <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> á <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Vista"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nei, takk"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"aðgangsorð"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"heimilisfang"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditkort"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"notandanafn"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"netfang"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Sýndu stillingu og leitaðu skjóls."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Fólk sem statt er á strandsvæðum eða við ár á tafarlaust að leita öryggis á svæðum sem eru í meiri hæð yfir sjávarmáli."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sýndu stillingu og leitaðu skjóls."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ffd363c..b65805e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1185,7 +1185,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"App <xliff:g id="NAME">%s</xliff:g> visualizzata sopra altre app"</string>
- <string name="alert_windows_notification_title" msgid="3697657294867638947">"App <xliff:g id="NAME">%s</xliff:g> visualiz. sopra altre app"</string>
+ <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="3367294525884949878">"DISATTIVA"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparazione della <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Passa alla modalità di immissione testo per inserire l\'ora."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Passa alla modalità orologio per inserire l\'ora."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opzioni di compilazione automatica"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Impossibile compilare automaticamente i contenuti"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Salvare in <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Salvare <xliff:g id="TYPE">%1$s</xliff:g> in <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Salva"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No, grazie"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"password"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"indirizzo"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"carta di credito"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nome utente"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"indirizzo email"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Mantieni la calma e cerca riparo nelle vicinanze."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuare immediatamente le zone costiere e in riva ai fiumi e recarsi in un luogo più sicuro, ad esempio un\'altura."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantieni la calma e cerca riparo nelle vicinanze."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index de88b08..fe61600 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -412,10 +412,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"מאפשר לאפליקציה לגשת לתכונות הטלפון של המכשיר. אישור זה מתיר לאפליקציה לגלות את מספר הטלפון ואת זיהויי המכשיר, האם שיחה פעילה ואת המספר המרוחק המחובר באמצעות שיחה."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ניתוב שיחות דרך המערכת"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"מאפשרת לאפליקציה לנתב את השיחות דרך המערכת כדי לשפר את חוויית השיחה."</string>
- <!-- no translation found for permlab_readPhoneNumbers (6108163940932852440) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneNumbers (8559488833662272354) -->
- <skip />
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"גישה למספרי הטלפון"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"מתירה לאפליקציה גישה למספרי הטלפון במכשיר."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"מנע מהטאבלט לעבור למצב שינה"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"מניעת מעבר למצב שינה בטלוויזיה"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"מניעת מעבר הטלפון למצב שינה"</string>
@@ -1227,8 +1225,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"תצוגה של <xliff:g id="NAME">%s</xliff:g> מעל אפליקציות אחרות"</string>
- <!-- no translation found for alert_windows_notification_title (3697657294867638947) -->
- <skip />
+ <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="3367294525884949878">"כבה"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"הכנת <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1797,19 +1794,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"העבר למצב קלט טקסט לצורך הזנת השעה"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"העבר למצב שעון לצורך הזנת השעה"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"אפשרויות מילוי אוטומטי"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"לא ניתן למלא את התוכן באופן אוטומטי"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"לשמור ב-<xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"לשמור <xliff:g id="TYPE">%1$s</xliff:g> ב-<xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"שמור"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"לא, תודה"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"סיסמה"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"כתובת"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"כרטיס אשראי"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"שם משתמש"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"כתובת אימייל"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"הישאר רגוע וחפש מחסה בקרבת מקום."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"יש להתפנות מיידית מאזורים הסמוכים לחופים ולנהרות למקום בטוח יותר, כגון שטח גבוה יותר."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"הישאר רגוע וחפש מחסה בקרבת מקום."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index a600652..071bc0b 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"時刻をテキストで入力するモードに切り替えます。"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"時刻を時計で入力するモードに切り替えます。"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"自動入力のオプション"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"コンテンツを自動入力できません"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> に保存しますか?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g>を <xliff:g id="LABEL">%2$s</xliff:g> に保存しますか?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"はい"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"いいえ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"パスワード"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"住所"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"クレジット カード"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ユーザー名"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"メールアドレス"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"強い揺れに備えてください"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"沿岸部の方はただちに高台へ避難してください"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"強い揺れと津波に注意してください"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index b9d496b..0fce14b 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"დროის შეყვანისთვის ტექსტის შეყვანის რეჟიმზე გადართვა."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"დროის შეყვანისთვის საათის რეჟიმზე გადართვა."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ავტომატური შევსების ვარიანტები"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"კონტენტის ავტომატური შევსება ვერ მოხერხდება"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"გსურთ „<xliff:g id="LABEL">%1$s</xliff:g>“-ში შენახვა?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"გსურთ, შეინახოთ <xliff:g id="TYPE">%1$s</xliff:g> „<xliff:g id="LABEL">%2$s</xliff:g>“-ში?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"შენახვა"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"არა, გმადლობთ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"პაროლი"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"მისამართი"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"საკრედიტო ბარათი"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"მომხმარებლის სახელი"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ელფოსტის მისამართი"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"შეინარჩუნეთ სიმშვიდე და იპოვეთ ახლომდებარე თავშესაფარი."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"დაუყოვნებლივ გადაინაცვლეთ სანაპირო რეგიონებიდან და მდინარისპირა ტერიტორიებიდან უსაფრთხო ადგილზე (მაგალითად, შემაღლებულ ადგილზე)."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"შეინარჩუნეთ სიმშვიდე და იპოვეთ ახლომდებარე თავშესაფარი."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 01088aa..bf7fdf6 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1733,19 +1733,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Уақытты енгізу үшін мәтін енгізу режиміне өтіңіз."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Уақытты енгізу үшін сағат режиміне өтіңіз."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Автотолтыру опциялары"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Мазмұндар автотолтырылмайды"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> жүйесінде сақталсын ба?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> деректері <xliff:g id="LABEL">%2$s</xliff:g> жүйесінде сақталсын ба?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> <xliff:g id="LABEL">%3$s</xliff:g> ішіне сақтау керек пе?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> <xliff:g id="LABEL">%4$s</xliff:g> ішіне сақтау керек пе?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Сақтау"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Жоқ, рақмет"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"құпия сөз"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"мекенжай"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"несие картасы"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"пайдаланушы аты"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"электрондық пошта мекенжайы"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Сабыр сақтап, жақын жерден баспана іздеңіз."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Жағалау аймақтан биіктеу қауіпсіз жерге дереу көшіңіз."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Сабыр сақтап, жақын жерден баспана іздеңіз."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 5e56ed0..236e201 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1734,19 +1734,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ប្តូរទៅមុខងារបញ្ចូលអក្សរសម្រាប់ការបញ្ចូលម៉ោង។"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ប្តូរទៅមុខងារនាឡិកាសម្រាប់ការបញ្ចូលម៉ោង។"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ជម្រើសបំពេញដោយស្វ័យប្រវត្តិ"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"មិនអាចបំពេញមាតិកាដោយស្វ័យប្រវត្តិបានទេ"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"រក្សាទុកទៅក្នុង <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"រក្សាទុក <xliff:g id="TYPE">%1$s</xliff:g> ទៅក្នុង <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"រក្សាទុក"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"ទេ អរគុណ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"ពាក្យសម្ងាត់"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"អាសយដ្ឋាន"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"បណ្ណឥណទាន"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ឈ្មោះអ្នកប្រើប្រាស់"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"អាសយដ្ឋានអ៊ីមែល"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"សូមរក្សាភាពស្ងប់ស្ងាត់ ហើយស្វែងរកជម្រកសុវត្ថិភាពដែលនៅជិត។"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ភៀសខ្លួនជាបន្ទាន់ពីតំបន់ឆ្នេរ និងតំបន់តាមមាត់ទន្លេទៅកាន់កន្លែងដែលមានសុវត្ថិភាពជាងនេះ ដូចជាទីទួលណាមួយ។"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"សូមរក្សាភាពស្ងប់ស្ងាត់ ហើយស្វែងរកជម្រកសុវត្ថិភាពដែលនៅជិត។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 27b629a..45bff7a 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1733,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ಸಮಯವನ್ನು ನಮೂದಿಸಲು ಪಠ್ಯದ ನಮೂನೆಗೆ ಬದಲಿಸಿ."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ಸಮಯವನ್ನು ನಮೂದಿಸಲು ಗಡಿಯಾರದ ನಮೂನೆಗೆ ಬದಲಿಸಿ."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ಸ್ವಯಂತುಂಬುವಿಕೆ ಆಯ್ಕೆಗಳು"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ವಿಷಯಗಳು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಭರ್ತಿಯಾಗಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> ನಲ್ಲಿ ಉಳಿಸಬೇಕೆ?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ಅನ್ನು <xliff:g id="LABEL">%2$s</xliff:g> ನಲ್ಲಿ ಉಳಿಸಬೇಕೆ?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"ಉಳಿಸಿ"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"ಬೇಡ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"ಪಾಸ್ವರ್ಡ್"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ವಿಳಾಸ"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ಬಳಕೆದಾರರ ಹೆಸರು"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ಇಮೇಲ್ ವಿಳಾಸ"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"ಶಾಂತರಾಗಿರಿ ಮತ್ತು ಸಮೀಪದಲ್ಲೆಲ್ಲಾದರೂ ಆಶ್ರಯ ಪಡೆದುಕೊಳ್ಳಿ."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ಕರಾವಳಿ ಪ್ರದೇಶಗಳು ಮತ್ತು ನದಿ ತೀರಗಳಿಂದ ತಕ್ಷಣವೇ ಎತ್ತರದ ಪ್ರದೇಶಗಳಂತಹ ಸುರಕ್ಷಿತ ಸ್ಥಳಕ್ಕೆ ಹೋಗಿ."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ಶಾಂತರಾಗಿರಿ ಮತ್ತು ಸಮೀಪದಲ್ಲೆಲ್ಲಾದರೂ ಆಶ್ರಯ ಪಡೆದುಕೊಳ್ಳಿ."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 24e4676..8133d13 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"시간 입력을 위해 텍스트 입력 모드로 전환합니다."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"시간 입력을 위해 시계 모드로 전환합니다."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"자동완성 옵션"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"콘텐츠를 자동완성할 수 없습니다."</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g>에 저장하시겠습니까?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g>을(를) <xliff:g id="LABEL">%2$s</xliff:g>에 저장하시겠습니까?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"저장"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"사용 안함"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"비밀번호"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"주소"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"신용카드"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"사용자 이름"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"이메일 주소"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"침착하게 가까운 대피소를 찾으세요."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"즉시 해안 지대나 강가에서 떨어져 고지대 등 안전한 장소로 대피하세요."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"침착하게 가까운 대피소를 찾으세요."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 7e417f1..f4d15aa 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1186,7 +1186,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> колдонмосун башка терезелердин үстүнөн көрсөтүү"</string>
- <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> колд. башк-дын үст. көрсөт-дө"</string>
+ <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="3367294525884949878">"ӨЧҮРҮҮ"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> даярдалууда"</string>
@@ -1733,19 +1733,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Убакытты текст киргизүү режиминде киргизиңиз."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Убакытты дубал саатынын режиминде киргизиңиз."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Автотолтуруу опциялары"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Мазмундарды автотолтуруу мүмкүн эмес"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> кызматында сакталсынбы?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="LABEL">%2$s</xliff:g> кызматында сакталсынбы?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g> менен <xliff:g id="TYPE_1">%2$s</xliff:g> <xliff:g id="LABEL">%3$s</xliff:g> кызматында сакталсынбы?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> жана <xliff:g id="TYPE_2">%3$s</xliff:g> <xliff:g id="LABEL">%4$s</xliff:g> кызматында сакталсынбы?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Сактоо"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Жок, рахмат"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"сырсөз"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"дарек"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"насыя картасы"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"колдонуучунун аты"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"электрондук почта дареги"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Эс алып, жакын жерден калканч издеңиз."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Деңиз жана дарыя жээгинде жайгашкан аймактардан бийик тоо сыяктуу коопсуз жерге тезинен чыгып кетиңиз."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Эс алып, жакын жерден калканч издеңиз."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 0603d1c..2040bdf 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ສະຫຼັບໄປໃຊ້ໂໝດປ້ອນຂໍ້ຄວາມສຳລັບການປ້ອນເວລາ."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ສະຫຼັບໄປໃຊ້ໂໝດໂມງສຳລັບການປ້ອນເວລາ."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ຕົວເລືອກການຕື່ມຂໍ້ມູນອັດຕະໂນມັດ"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ບໍ່ສາມາດຕື່ມຂໍ້ມູນເນື້ອຫາອັດຕະໂນມັດໄດ້"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"ບັນທຶກໄປໃສ່ <xliff:g id="LABEL">%1$s</xliff:g> ບໍ?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"ບັນທຶກ <xliff:g id="TYPE">%1$s</xliff:g> ໄປໃສ່ <xliff:g id="LABEL">%2$s</xliff:g> ບໍ?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"ບັນທຶກ"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"ບໍ່, ຂອບໃຈ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"ລະຫັດຜ່ານ"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ທີ່ຢູ່"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ບັດເຄຣດິດ"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ຊື່ຜູ້ໃຊ້"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ທີ່ຢູ່ອີເມລ"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"ໃຈເຢັນໆ ແລະ ຊອກຫາບ່ອນພັກຢູ່ໃກ້ໆ."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ອົບພະຍົບອອກຈາກເຂດຊາຍຝັ່ງທະເລ ແລະ ບໍລິເວນແມ່ນ້ຳໄປບ່ອນທີ່ປອດໄພກວ່າ ເຊັ່ນ: ບ່ອນສູງ ໂດຍທັນທີ."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ໃຈເຢັນໆ ແລະ ຊອກຫາບ່ອນພັກຢູ່ໃກ້ໆ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 2345bdf..c84ab90 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1794,19 +1794,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Laiko įvestį pateikti perjungus į teksto įvesties režimą."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Laiko įvestį pateikti perjungus į laikrodžio režimą."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Automatinio pildymo parinktys"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Turinio negalima pildyti automatiškai"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Išsaugoti skiltyje „<xliff:g id="LABEL">%1$s</xliff:g>“?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Išsaugoti <xliff:g id="TYPE">%1$s</xliff:g> skiltyje „<xliff:g id="LABEL">%2$s</xliff:g>“?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Išsaugoti"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ne, ačiū"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"slaptažodį"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresą"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kredito kortelę"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"naudotojo vardas"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"el. pašto adresas"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Nesijaudinkite ir ieškokite prieglobsčio netoliese."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Nedelsdami pasitraukite nuo pakrančių ir paupių. Eikite į saugią vietą, pvz., vietą, kuri yra aukštai."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Nesijaudinkite ir ieškokite prieglobsčio netoliese."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9e8a34e..f16b129 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1763,19 +1763,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Lai ievadītu laiku, ieslēdziet teksta ievades režīmu."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Lai ievadītu laiku, ieslēdziet pulksteņa režīmu."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Automātiskās aizpildes opcijas"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Saturu nevar automātiski aizpildīt."</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Vai saglabāt pakalpojumā <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Vai saglabāt <xliff:g id="TYPE">%1$s</xliff:g> pakalpojumā <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Saglabāt"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nē, paldies"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"paroli"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresi"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kredītkartes informāciju"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"lietotājvārds"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-pasta adrese"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Saglabājiet mieru un meklējiet tuvumā patvērumu."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Nekavējoties pametiet piekrastes un upju zonas un dodieties uz drošākām (piemēram, augstākām) vietām."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Saglabājiet mieru un meklējiet tuvumā patvērumu."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index b073652..2fb9553 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1735,19 +1735,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Префрлете се на режимот за внесување текст за да внесете време."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Префрлете се на режимот за часовник за да внесете време."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Опции за автоматско пополнување"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Содржините не може автоматски да се пополнат"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Да се зачува во <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Да се зачува <xliff:g id="TYPE">%1$s</xliff:g> во <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Да се зачуваат <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> во <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Да се зачуваат <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> во <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Зачувај"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Не, благодарам"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"лозинка"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"адреса"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"кредитна картичка"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"корисничко име"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"адреса на е-пошта"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Бидете смирени и побарајте засолниште во близина."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Итна евакуација од крајбрежните региони и областите покрај реки на побезбедно место, како на пр., терени на повисока надморска височина."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Бидете смирени и побарајте засолниште во близина."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 84aa13c..5cfc234b 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1733,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"സമയം നൽകുന്നതിന് ടെക്സ്റ്റ് ഇൻപുട്ട് മോഡിലേക്ക് മാറുക."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"സമയം നൽകുന്നതിന് ക്ലോക്ക് മോഡിലേക്ക് മാറുക."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"സ്വയമേവ പൂരിപ്പിക്കൽ ഓപ്ഷനുകൾ"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ഉള്ളടക്കങ്ങൾ സ്വയമേവ പൂരിപ്പിക്കാൻ കഴിയില്ല"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> എന്നതിലേക്ക് സംരക്ഷിക്കണോ?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="LABEL">%2$s</xliff:g> എന്നതിലേക്ക് സംരക്ഷിക്കണോ?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"സംരക്ഷിക്കുക"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"വേണ്ട, നന്ദി"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"പാസ്വേഡ്"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"വിലാസം"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ക്രെഡിറ്റ് കാർഡ്"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ഉപയോക്തൃനാമം"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"വിലാസം നൽകുക"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"പരിഭ്രമിക്കാതിരിക്കുക, അടുത്തുള്ള അഭയകേന്ദ്രം തേടുക."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"തീരപ്രദേശങ്ങളിൽ നിന്നും നദിക്കരകളിൽ നിന്നും ആളുകളെ ഉടനടി ഒഴിപ്പിച്ച് ഉയർന്ന ഭൂമിയിൽ എത്തിക്കുക."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"പരിഭ്രമിക്കാതിരിക്കുക, അടുത്തുള്ള അഭയകേന്ദ്രം തേടുക."</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 4cd99a3..fb842b2 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1730,19 +1730,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Цагийг оруулахын тулд текст оруулах горимд шилжүүлнэ үү."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Цагийг оруулахын тулд цагийн горимд шилжүүлнэ үү."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Автоматаар бөглөх хэсгийн сонголт"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Агуулгыг автоматаар бөглөх боломжгүй"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g>-д хадгалах уу?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g>-г <xliff:g id="LABEL">%2$s</xliff:g>-д хадгалах уу?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Хадгалах"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Үгүй, баярлалаа"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"нууц үг"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"хаяг"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"кредит карт"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"хэрэглэгчийн нэр"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"имэйл хаяг"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Эргийн бүс, голын эргийн бүсээс өндөрлөг газар зэрэг аюулгүй газар руу нэн даруй шилжинэ үү."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 2f77ffc..538d626 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -406,10 +406,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"डिव्हाइसच्या फोन वैशिष्ट्यांवर प्रवेश करण्यास अॅप ला अनुमती देते. ही परवानगी कॉल सक्रिय असला किंवा नसला तरीही, फोन नंबर आणि डिव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रीमोट नंबर निर्धारित करण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"प्रणालीच्या माध्यमातून कॉल रूट करा"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करण्याचा अनुभव सुधारण्यासाठी अॅपला त्याचे कॉल प्रणालीच्या माध्यमातून रूट करू देते."</string>
- <!-- no translation found for permlab_readPhoneNumbers (6108163940932852440) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneNumbers (8559488833662272354) -->
- <skip />
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फोन नंबर वाचा"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"अॅपला डिव्हाइसच्या फोन नंबरमध्ये प्रवेश करण्याची अनुमती देते."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टॅबलेट निष्क्रिय होण्यापासून प्रतिबंधित करा"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"निष्क्रिय होण्यापासून प्रतिबंध करा"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फोन निष्क्रिय होण्यापासून प्रतिबंधित करा"</string>
@@ -1188,8 +1186,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> इतर अॅप्सवर प्रदर्शित करीत आहे"</string>
- <!-- no translation found for alert_windows_notification_title (3697657294867638947) -->
- <skip />
+ <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="3367294525884949878">"बंद करा"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> तयार करीत आहे"</string>
@@ -1740,15 +1737,17 @@
<skip />
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> वर जतन करायचे?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="LABEL">%2$s</xliff:g> वर <xliff:g id="TYPE">%1$s</xliff:g> जतन करायचे?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"जतन करा"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"नाही धन्यवाद"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"संकेतशब्द"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"पत्ता"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"क्रेडिट कार्ड"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"वापरकर्तानाव"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ईमेल पत्ता"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"शांत रहा आणि जवळपास निवारा शोधा."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"किनारपट्टीचे प्रदेश आणि नदीकाठची क्षेत्रे त्वरित रिकामी करून उंच मैदानासारख्या अधिक सुरक्षित ठिकाणी जा."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शांत रहा आणि जवळपास निवारा शोधा."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 9211121..ef5883a 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Beralih ke mod input teks untuk input masa."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Beralih ke mod jam untuk input masa."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Pilihan autolengkap"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Kandungan tidak boleh dilengkapkan secara automatik"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Simpan ke <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Simpan <xliff:g id="TYPE">%1$s</xliff:g> ke <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Simpan"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Tidak, terima kasih"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"kata laluan"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"alamat"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kad kredit"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nama pengguna"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"alamat e-mel"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Bertenang dan cari perlindungan di kawasan yang berdekatan."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Segera beredar dari kawasan pinggir laut dan tepi sungai dan berpindah ke tempat yang lebih selamat seperti kawasan tinggi."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bertenang dan cari perlindungan di kawasan yang berdekatan."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index e8e0da3..ad0602e 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1733,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"အချိန်ထည့်သွင်းရန် စာသားထည့်သွင်းမှုမုဒ်သို့ ပြောင်းပါ။"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"အချိန်ထည့်သွင်းမှုအတွက် နာရီမုဒ်သို့ ပြောင်းပါ။"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"အော်တိုဖြည့် ရွေးချယ်စရာများ"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"အကြောင်းအရာများကို အော်တိုဖြည့်၍မရပါ"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> သို့ သိမ်းဆည်းလိုပါသလား။"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ကို <xliff:g id="LABEL">%2$s</xliff:g> သို့ သိမ်းဆည်းလိုပါသလား။"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"သိမ်းရန်"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"မလိုပါ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"စကားဝှက်"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"လိပ်စာ"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ခရက်တစ်ကတ်"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"အသုံးပြုသူအမည်"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"အီးမေးလ်လိပ်စာ"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"စိတ်ငြိမ်ငြိမ်ထားပြီး အနီးအနားတဝိုက်တွင် ခိုနားစရာ နေရာရှာပါ။"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ကမ်းရိုးတန်းနှင့် မြစ်ကမ်းရိုးတစ်လျှောက်ရှိ နေရာဒေသတို့မှ ချက်ချင်းထွက်ခွာပြီး ဘေးကင်းရာကုန်းမြင့်ဒေသသို့ ပြောင်းရွှေ့ပါ။"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"စိတ်ငြိမ်ငြိမ်ထားပြီး အနီးအနားတဝိုက်တွင် ခိုနားစရာ နေရာရှာပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 4db1c7e..974d55f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -406,10 +406,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lar appen bruke enhetens telefonfunksjoner. Med denne tillatelsen kan appen finne telefonnummer og enhets-ID-er, registrere om en samtale pågår, og se det eksterne nummeret det opprettes en forbindelse med via oppringing."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"send anrop gjennom systemet"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Lar appen sende anrop gjennom systemet for å forbedre anropsopplevelsen."</string>
- <!-- no translation found for permlab_readPhoneNumbers (6108163940932852440) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneNumbers (8559488833662272354) -->
- <skip />
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"les telefonnumre"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Gir appen tilgang til telefonnumrene til enheten."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"hindre nettbrettet fra å gå over til sovemodus"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"hindre TV-en i å gå i hvilemodus"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"forhindre telefonen fra å sove"</string>
@@ -1187,8 +1185,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> vises over andre apper"</string>
- <!-- no translation found for alert_windows_notification_title (3697657294867638947) -->
- <skip />
+ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> vises over andre apper"</string>
<string name="alert_windows_notification_message" msgid="8917232109522912560">"Hvis du ikke vil at <xliff:g id="NAME">%s</xliff:g> skal bruke denne funksjonen, kan du trykke for å åpne innstillingene og slå den av."</string>
<string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"SLÅ AV"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Forbereder <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1735,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Bytt til tekstinndatamodus for tidsinndata."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Bytt til klokkemodus for tidsinndata."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Alternativer for autofyll"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Innhold kan ikke fylles ut automatisk"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Vil du lagre i <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Vil du lagre <xliff:g id="TYPE">%1$s</xliff:g> i <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Lagre"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nei takk"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"passord"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresse"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kredittkort"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"brukernavn"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-postadresse"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Hold deg rolig og søk ly i nærheten."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuer umiddelbart fra kyst- og elveområder til et tryggere sted, for eksempel høyt terreng."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hold deg rolig og søk ly i nærheten."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index fe910ae..8161fb1 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -406,10 +406,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"उपकरणको फोन विशेषताहरूको पहुँच गर्न अनुप्रयोगलाई अनुमति दिन्छ। यस अनुमतिले फोन नम्बर र उपकरणको IDs, कल सक्षम छ कि छैन र कलद्वारा जोडिएको टाढाको नम्बर निर्धारण गर्न अनुमति दिन्छ।"</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"प्रणाली मार्फत कल गर्न दिनुहोस्"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कल गर्दाको अनुभवलाई सुधार्न यस अनुप्रयोगलाई प्रणाली मार्फत कलहरू गर्न अनुमति दिन्छ।"</string>
- <!-- no translation found for permlab_readPhoneNumbers (6108163940932852440) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneNumbers (8559488833662272354) -->
- <skip />
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फोन नम्बरहरू पढ्ने"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"उक्त अनुप्रयोगलाई यस यन्त्रको फोन नम्बरहरूमाथि पहुँच राख्न दिनुहोस्।"</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ट्याब्लेटलाई निन्द्रामा जानबाट रोक्नुहोस्"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"TV निभ्नबाट जोगाउनुहोस्"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फोनलाई निदाउनबाट रोक्नुहोस्"</string>
@@ -1193,8 +1191,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> अन्य अनुप्रयोगहरूमा देखिँदैछ"</string>
- <!-- no translation found for alert_windows_notification_title (3697657294867638947) -->
- <skip />
+ <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="3367294525884949878">"निष्क्रिय पार्नुहोस्"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"तयारी गर्दै <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1741,19 +1738,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"समय इनपुट गर्न पाठ इनपुट मोडमा स्विच गर्नुहोस्।"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"समय इनपुट गर्न घडी मोडमा स्विच गर्नुहोस्।"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"स्वतः भरणका विकल्पहरू"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"सामग्रीहरूलाई स्वत: भरण गर्न मिल्दैन"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> मा सुरक्षित गर्ने हो?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> लाई <xliff:g id="LABEL">%2$s</xliff:g> मा सुरक्षित गर्ने हो?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"सुरक्षित गर्नुहोस्"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"पर्दैन, धन्यवाद"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"पासवर्ड"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ठेगाना"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"क्रेडिट कार्ड"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"प्रयोगकर्ताको नाम"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"इमेल ठेगाना"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"तटीय क्षेत्र र नदीछेउका ठाउँहरू छाडी उच्च सतहमा अवस्थित कुनै अझ सुरक्षित ठाउँमा जानुहोस्।"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1bfc77a..15c8ff3 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Schakel naar de tekstinvoermodus om de tijd in te voeren."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Schakel naar de klokmodus om de tijd in te voeren."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opties voor automatisch aanvullen"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Content kan niet automatisch worden aangevuld"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Opslaan in <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> opslaan in <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Opslaan"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nee, bedankt"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"Wachtwoord"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"Adres"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"Creditcard"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"gebruikersnaam"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-mailadres"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Blijf kalm en zoek onderdak in de buurt."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Verlaat kustgebieden en rivieroevers onmiddellijk en zoek een hoger gelegen gebied op."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Blijf kalm en zoek onderdak in de buurt."</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 3fe7fb0..ea1194a 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -91,12 +91,12 @@
<string name="CLIRPermanent" msgid="3377371145926835671">"ਤੁਸੀਂ ਕਾਲਰ ID ਸੈਟਿੰਗ ਨਹੀਂ ਬਦਲ ਸਕਦੇ।"</string>
<string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ਕੋਈ ਡੈਟਾ ਸੇਵਾ ਨਹੀਂ"</string>
<string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"ਕੋਈ ਸੰਕਟਕਾਲੀਨ ਸੇਵਾ ਨਹੀਂ"</string>
- <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ਕੋਈ ਅਵਾਜ਼ੀ ਸੇਵਾ ਨਹੀਂ"</string>
- <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ਕੋਈ ਅਵਾਜ਼ੀ/ਸੰਕਟਕਾਲੀਨ ਸੇਵਾ ਨਹੀਂ"</string>
+ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ਕੋਈ ਆਵਾਜ਼ੀ ਸੇਵਾ ਨਹੀਂ"</string>
+ <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ਕੋਈ ਆਵਾਜ਼ੀ/ਸੰਕਟਕਾਲੀਨ ਸੇਵਾ ਨਹੀਂ"</string>
<string name="RestrictedOnDataContent" msgid="8997474569390996587">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਡੈਟਾ ਸੇਵਾ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
<string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
- <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਅਵਾਜ਼ੀ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
- <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਅਵਾਜ਼ੀ ਅਤੇ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਆਵਾਜ਼ੀ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਆਵਾਜ਼ੀ ਅਤੇ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ਸਿਗਨਲ ਪ੍ਰਾਪਤੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਸਿਸਟਮ > ਨੈੱਟਵਰਕ ਅਤੇ ਇੰਟਰਨੈੱਟ > ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ > ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ \'ਤੇ ਚੁਣੀ ਗਈ ਕਿਸਮ ਨੂੰ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="peerTtyModeFull" msgid="6165351790010341421">"ਪੀਅਰ ਨੇ TTY Mode FULL ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
@@ -179,8 +179,8 @@
<string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ"</string>
<string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> ਮੁਤਾਬਕ"</string>
<string name="work_profile_deleted" msgid="5005572078641980632">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਮਿਟਾਈ ਗਈ"</string>
- <string name="work_profile_deleted_description" msgid="1100529432509639864">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਗੁੰਮ ਹੋਣ ਕਾਰਨ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਮਿਟਾਇਆ ਗਿਆ"</string>
- <string name="work_profile_deleted_details" msgid="6307630639269092360">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਜਾਂ ਤਾਂ ਗੁੰਮ ਹੈ ਜਾਂ ਖਰਾਬ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ, ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਸਬੰਧਿਤ ਡੈਟਾ ਮਿਟਾਇਆ ਗਿਆ ਹੈ। ਸਹਾਇਤਾ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+ <string name="work_profile_deleted_description" msgid="1100529432509639864">"ਗੁੰਮਸ਼ੁਦਾ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਦੇ ਕਾਰਨ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਮਿਟਾਇਆ ਗਿਆ"</string>
+ <string name="work_profile_deleted_details" msgid="6307630639269092360">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਜਾਂ ਤਾਂ ਗੁੰਮਸ਼ੁਦਾ ਹੈ ਜਾਂ ਖਰਾਬ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ, ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਸਬੰਧਿਤ ਡੈਟਾ ਮਿਟਾਇਆ ਗਿਆ ਹੈ। ਸਹਾਇਤਾ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹੁਣ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="network_logging_notification_title" msgid="6399790108123704477">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string>
<string name="network_logging_notification_text" msgid="7930089249949354026">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
@@ -1466,7 +1466,7 @@
<string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ"</string>
<string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ"</string>
- <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ \'ਤੇ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
+ <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
<string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਬਦਲਣ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
<string name="user_switched" msgid="3768006783166984410">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
@@ -1737,22 +1737,24 @@
<skip />
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ਨੂੰ <xliff:g id="LABEL">%2$s</xliff:g> ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"ਰੱਖਿਅਤ ਕਰੋ"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"ਪਾਸਵਰਡ"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ਪਤਾ"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ਕ੍ਰੈਡਿਟ ਕਾਰਡ"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ਵਰਤੋਂਕਾਰ ਨਾਮ"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ਈਮੇਲ ਪਤਾ"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"ਸ਼ਾਂਤ ਰਹੋ ਅਤੇ ਆਸ-ਪਾਸ ਪਨਾਹ ਮੰਗੋ।"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ਤੁਰੰਤ ਤੱਟੀ ਖੇਤਰਾਂ ਅਤੇ ਨਦੀ ਦੇ ਕਿਨਾਰੇ ਵਾਲੇ ਖੇਤਰਾਂ ਨੂੰ ਖਾਲੀ ਕਰ ਕੇ ਕਿਸੇ ਸੁਰੱਖਿਅਤ ਸਥਾਨ \'ਤੇ ਚਲੇ ਜਾਓ ਜਿਵੇਂ ਕਿ ਉੱਚੀ ਜ਼ਮੀਨ।"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ਸ਼ਾਂਤ ਰਹੋ ਅਤੇ ਆਸ-ਪਾਸ ਪਨਾਹ ਮੰਗੋ।"</string>
<string name="etws_primary_default_message_test" msgid="2709597093560037455">"ਸੰਕਟਕਾਲੀਨ ਸੰਦੇਸ਼ ਟੈਸਟ"</string>
<string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
<string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
- <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM ਅਨੁਕੂਲਿਤ ਨਹੀਂ ਹੈ"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ"</string>
<string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
<string name="mmcc_illegal_me" msgid="4438696681169345015">"ਫ਼ੋਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 5f61e89..d7572a0 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1794,19 +1794,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Aby wprowadzić czas, włącz tryb wprowadzania tekstu."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Aby wprowadzić czas, włącz tryb zegara."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcje autouzupełniania"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Nie można automatycznie uzupełnić treści"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Zapisać w: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Zapisać element <xliff:g id="TYPE">%1$s</xliff:g> w: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Zapisz"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nie, dziękuję"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"hasło"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adres"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"karta kredytowa"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nazwa użytkownika"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adres e-mail"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Zachowaj spokój i poszukaj schronienia w pobliżu."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Niezwłocznie ewakuuj się z regionów nabrzeżnych i położonych przy rzekach w bezpieczniejsze miejsce, np. na wzniesienie."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachowaj spokój i poszukaj schronienia w pobliżu."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 9c059f9..1231a8b 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Alterne para o modo de entrada de texto para informar o horário."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Alterne para o modo de relógio para informar o horário."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opções de preenchimento automático"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Não é possível preencher os conteúdos automaticamente"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Salvar em <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Salvar <xliff:g id="TYPE">%1$s</xliff:g> em <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Salvar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Não, obrigado"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"senha"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"endereço"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"cartão de crédito"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nome de usuário"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"endereço de e-mail"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Fique calmo e procure um abrigo por perto."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Saia imediatamente de regiões costeiras e áreas ribeirinhas e vá para um lugar mais seguro, como terrenos elevados."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Fique calmo e procure um abrigo por perto."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 8d89c17..c533a03 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Mude para o modo de introdução de texto para a introdução da hora."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Mude para o modo de relógio para a introdução da hora."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opções de preenchimento automático"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Não é possível preencher automaticamente o conteúdo"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Pretende guardar no <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Pretende guardar o(a) <xliff:g id="TYPE">%1$s</xliff:g> no <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Guardar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Não, obrigado"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"palavra-passe"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"endereço"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"cartão de crédito"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nome de utilizador"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"endereço de email"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Mantenha a calma e procure abrigo nas proximidades."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandone imediatamente regiões costeiras e zonas ribeirinhas em direção a um local mais seguro, como um terreno elevado."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantenha a calma e procure abrigo nas proximidades."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 9c059f9..1231a8b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Alterne para o modo de entrada de texto para informar o horário."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Alterne para o modo de relógio para informar o horário."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opções de preenchimento automático"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Não é possível preencher os conteúdos automaticamente"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Salvar em <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Salvar <xliff:g id="TYPE">%1$s</xliff:g> em <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Salvar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Não, obrigado"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"senha"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"endereço"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"cartão de crédito"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nome de usuário"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"endereço de e-mail"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Fique calmo e procure um abrigo por perto."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Saia imediatamente de regiões costeiras e áreas ribeirinhas e vá para um lugar mais seguro, como terrenos elevados."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Fique calmo e procure um abrigo por perto."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 007ac8c..8a6b349 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1763,19 +1763,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Pentru a introduce ora, comutați la modul de introducere a textului."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Pentru a introduce ora, comutați la modul ceas."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opțiuni de completare automată"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Conținutul nu poate fi completat automat"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Salvați în <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Salvați <xliff:g id="TYPE">%1$s</xliff:g> în <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Salvați"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nu, mulțumesc"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"parolă"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresă"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"card de credit"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"nume de utilizator"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adresă de e-mail"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Păstrați-vă calmul și căutați un adăpost în apropiere."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Părăsiți imediat zonele de coastă și din apropierea râurilor și îndreptați-vă spre un loc mai sigur, cum ar fi o zonă aflată la înălțime."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Păstrați-vă calmul și căutați un adăpost în apropiere."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c64f929..40fe776 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1794,19 +1794,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Чтобы ввести время, перейдите в режим ввода текста."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Чтобы ввести время, перейдите в режим часов."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Параметры автозаполнения"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Ошибка автозаполнения"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Сохранить в <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g>: сохранить в <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Сохранить"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Нет, спасибо"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"Пароль"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"Адрес"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"Банковская карта"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"имя пользователя"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"адрес электронной почты"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Сохраняйте спокойствие и поищите укрытие поблизости."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Немедленно эвакуируйтесь из прибрежной зоны в более высокое место."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Сохраняйте спокойствие и поищите укрытие поблизости."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 2a76c97..cd4cebdd 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -406,10 +406,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"උපාංගයේ දුරකථන විශේෂාංග වෙත ප්රවේශයට යෙදුමට ඉඩ දෙයි. ඇමතුම සක්රිය වුවත්, සහ ඇමතුමකින් දුරස්ථ අංකය සම්බන්ධ වුවත් දුරකථන අංකය සහ උපාංග ID හඳුනා ගැනීමට මෙම අවසරය යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"පද්ධතිය හරහා ඇමතුම් මාර්ගගත කරන්න"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"ඇමතුම් අත්දැකීම වැඩිදියුණු කිරීම සඳහා යෙදුමට පද්ධතිය හරහා එහි ඇමතුම් මාර්ගගත කිරීමට ඉඩ දෙයි."</string>
- <!-- no translation found for permlab_readPhoneNumbers (6108163940932852440) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneNumbers (8559488833662272354) -->
- <skip />
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"දුරකථන අංක කියවන්න"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"උපාංගයේ දුරකථන අංක වෙත ප්රවේශයට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ටැබ්ලටය නින්දෙන් වැළක්වීම"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"රූපවාහිනිය නින්දට යාමෙන් නවත්වන්න"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"දුරකථනය නින්දට යාමෙන් වළකන්න"</string>
@@ -1189,8 +1187,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"අනෙක් යෙදුම්වලට උඩින් <xliff:g id="NAME">%s</xliff:g> සංදර්ශනය කරමින්"</string>
- <!-- no translation found for alert_windows_notification_title (3697657294867638947) -->
- <skip />
+ <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="3367294525884949878">"ක්රියා විරහිත කරන්න"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> සූදානම් කරමින්"</string>
@@ -1737,19 +1734,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"වේලා ආදානය සඳහා ආදාන ප්රකාරය වෙත මාරු වෙන්න."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"වේලා ආදානය සඳහා ඔරලෝසු ප්රකාරය වෙත මාරු වෙන්න."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ස්වයංක්රිය පිරවුම් විකල්ප"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"අන්තර්ගතය ස්වයං පිරවුම් කළ නොහැකිය"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> වෙත සුරකින්නද?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="LABEL">%2$s</xliff:g> වෙත සුරකින්නද?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"සුරකින්න"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"එපා ස්තූතියි"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"මුරපදය"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ලිපිනය"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ණය කාඩ්පත"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"පරිශීලක නාමය"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ඊ-තැපැල් ලිපිනය"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"සන්සුන්ව ඉන්න සහ අවට ඇති නවාතැන් පහසුකම් බලන්න."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"මුහුදු බඩ ප්රදේශ සහ ගංඉවුරු ප්රදේශ සිට ඉහළ ප්රදේශයක් වැනි ආරක්ෂිත තැනකට දැන්ම යන්න."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"සන්සුන්ව ඉන්න සහ අවට ඇති නවාතැන් පහසුකම් බලන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index a1b3ad4..71411f7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1794,19 +1794,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Ak chcete zadať čas, prepnite na textový režim vstupu"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Ak chcete zadať čas, prepnite na režim hodín."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Možnosti automatického dopĺňania"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Obsah nie je možné automaticky vyplniť"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Uložiť do zariadenia <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Uložiť <xliff:g id="TYPE">%1$s</xliff:g> do zariadenia <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Uložiť"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nie, vďaka"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"heslo"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditná karta"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"používateľské meno"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-mailová adresa"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Zachovajte pokoj a vyhľadajte úkryt v okolí."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Okamžite začnite evakuáciu z prímorských a nábrežných oblastí na bezpečnejšie miesto, napríklad do vyššie položených regiónov."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachovajte pokoj a vyhľadajte úkryt v okolí."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index f003c0b..5b76e79 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1794,19 +1794,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Preklopite na način za vnašanje besedila, da vnesete čas."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Preklopite na način ure, da vnesete čas."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Možnosti samodejnega izpolnjevanja"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Vsebine ni mogoče samodejno izpolniti"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Shrani v <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Shrani <xliff:g id="TYPE">%1$s</xliff:g> v <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Shrani"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"geslo"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"naslov"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditno kartico"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"uporabniško ime"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-poštni naslov"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite mirni in poiščite zavetje v bližini."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Takoj se umaknite z obalnih območij in bregov rek na varnejše mesto, na primer na višje ležeča mesta."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni in poiščite zavetje v bližini."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 05feb1a..d26b652 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1733,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Kalo te modaliteti i hyrjes së tekstit për hyrjen e kohës."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Kalo te modaliteti i orës për hyrjen e kohës."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opsionet e plotësimit automatik"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Përmbajtjet nuk mund të plotësohen automatikisht"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Të ruhet te <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Të ruhet <xliff:g id="TYPE">%1$s</xliff:g> te <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Ruaj"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Jo, faleminderit"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"fjalëkalimi"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"karta e kreditit"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"emri i përdoruesit"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adresa e mail-it"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Qëndro i qetë dhe kërko strehim në afërsi."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuohu menjëherë nga rajonet bregdetare dhe zonat pranë lumenjve drejt një vendi më të sigurt, si për shembull në një terren të ngritur."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Qëndro i qetë dhe kërko strehim në afërsi."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 8c7ad93..15456f8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1763,19 +1763,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Пређите у режим уноса текста ради уноса времена."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Пређите у режим сата ради уноса времена."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Опције аутоматског попуњавања"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Садржај не може аутоматски да се попуни"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Желите ли да сачувате у: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Желите ли да сачувате ставку <xliff:g id="TYPE">%1$s</xliff:g> у: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Сачувај"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Не, хвала"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"лозинка"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"адреса"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"кредитна картица"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"корисничко име"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"имејл адреса"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Останите мирни и потражите склониште у околини."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Одмах се склоните из приобалних региона и области поред река на неко безбедније место, на пример, на неко узвишење."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Останите мирни и потражите склониште у околини."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index cbb84af..90dfd681a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -282,7 +282,7 @@
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"få åtkomst till sensordata om dina vitalparametrar"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Hämta fönsterinnehåll"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Granska innehållet i ett fönster som du interagerar med."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivera Explore by Touch"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivera Explore by touch"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Objekt som användaren trycker på läses upp högt och skärmen kan utforskas med hjälp av rörelser."</string>
<string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Aktivera förbättrad webbtillgänglighet"</string>
<string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Skript kan installeras för att göra appens innehåll tillgängligare."</string>
@@ -853,9 +853,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Ta bort frågan"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Skicka fråga"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Röstsökning"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Aktivera Explore by Touch?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vill aktivera Explore by Touch. När funktionen är aktiv kan du höra eller se beskrivningar av vad du har under fingret eller utföra gester för att göra saker med surfplattan."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vill aktivera Explore by Touch. När funktionen är aktiv kan du höra eller se beskrivningar av vad du har under fingret eller utföra gester för att göra saker med telefonen."</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Aktivera Explore by touch?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vill aktivera Explore by touch. När funktionen är aktiv kan du höra eller se beskrivningar av vad du har under fingret eller utföra gester för att göra saker med surfplattan."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vill aktivera Explore by touch. När funktionen är aktiv kan du höra eller se beskrivningar av vad du har under fingret eller utföra gester för att göra saker med telefonen."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"för 1 månad sedan"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"För mer än en månad sedan"</string>
<plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -1732,19 +1732,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Byt till textinmatningsläget och ange tid."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Byt till klockläget och ange tid."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Alternativ för autofyll"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Det gick inte att fylla i innehållet automatiskt"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Vill du spara detta i <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Vill du spara <xliff:g id="TYPE">%1$s</xliff:g> i <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Spara <xliff:g id="TYPE_0">%1$s</xliff:g> och <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Spara <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> och <xliff:g id="TYPE_2">%3$s</xliff:g> i <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Spara"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Nej tack"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"lösenordet"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adressen"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditkortet"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"användarnamn"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-postadress"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Håll dig lugn och sök skydd i närheten."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Utrym kust- och flodområden omedelbart och förflytta er till en säkrare plats, till exempel ett högt beläget område."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Håll dig lugn och sök skydd i närheten."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 7cd8c3a..e7b12f0 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1730,19 +1730,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Badilisha iwe katika hali ya maandishi wakati wa kuweka muda."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Badilisha umbo liwe la saa ya mishale wakati wa kuweka muda."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Chaguo za kujaza otomatiki"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Maudhui hayawezi kujazwa kiotomatiki"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Ungependa kuhifadhi kwenye <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Ungependa kuhifadhi <xliff:g id="TYPE">%1$s</xliff:g> kwenye <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Hifadhi"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Hapana, asante"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"nenosiri"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"anwani"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kadi ya mikopo"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"jina la mtumiaji"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"anwani ya barua pepe"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Tulia na utafute hifadhi ya karibu."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ondoka mara moja kwenye maeneo ya ufuo na mito ili uende kwenye sehemu salama kama vile milimani."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tulia na utafute hifadhi ya karibu."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 16ced0a..1f81757 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1733,19 +1733,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"உரை உள்ளீட்டிற்காக, கடிகாரப் பயன்முறைக்கு மாற்றும்."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"நேர உள்ளீட்டிற்காக, கடிகாரப் பயன்முறைக்கு மாற்றும்."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"தன்னிரப்பி விருப்பங்கள்"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"உள்ளடக்கத்தைத் தானாக நிரப்ப முடியவில்லை"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> இல் சேமிக்கவா?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g>ஐ <xliff:g id="LABEL">%2$s</xliff:g> இல் சேமிக்கவா?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ஆகியவற்றை <xliff:g id="LABEL">%3$s</xliff:g> இல் சேமிக்கவா?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ஆகியவற்றை <xliff:g id="LABEL">%4$s</xliff:g> இல் சேமிக்கவா?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"சேமி"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"வேண்டாம்"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"கடவுச்சொல்"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"முகவரி"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"கிரெடிட் கார்டு"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"பயனர்பெயர்"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"மின்னஞ்சல் முகவரி"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"பதட்டப்படாதீர்கள், அருகில் ஏதேனும் பாதுகாப்பான இடம் உள்ளதா எனப் பாருங்கள்."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"கடலோரப் பகுதிகளிலும் ஆற்றங்கரைகளிலும் வசிப்பவர்கள் உடனடியாகப் பாதுகாப்பான இடத்திற்குச் (மேட்டுப்பகுதி) செல்லவும்."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"பதட்டப்படாதீர்கள், அருகில் ஏதேனும் பாதுகாப்பான இடம் உள்ளதா எனப் பாருங்கள்."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index c143d4f..6c489fd 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1733,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"సమయాన్ని నమోదు చేయడం కోసం వచన నమోదు మోడ్కి మారండి."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"సమయాన్ని నమోదు చేయడం కోసం గడియారం మోడ్కు మారండి."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"స్వీయ పూరింపు ఎంపికలు"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"కంటెంట్లను స్వీయ పూరింపు చేయడం సాధ్యపడదు"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g>కు సేవ్ చేయాలా?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g>ని <xliff:g id="LABEL">%2$s</xliff:g>కు సేవ్ చేయాలా?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"సేవ్ చేయి"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"వద్దు, ధన్యవాదాలు"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"పాస్వర్డ్"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"చిరునామా"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"క్రెడిట్ కార్డ్"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"వినియోగదారు పేరు"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ఇమెయిల్ చిరునామా"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"ప్రశాంతంగా ఉండండి మరియు దగ్గర్లో తలదాచుకోండి."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"వెంటనే తీర ప్రాంతాలు మరియు నదీ పరీవాహక ప్రాంతాలను ఖాళీ చేసి మెట్ట ప్రాంతాలకు తరలి వెళ్లండి."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ప్రశాంతంగా ఉండండి మరియు దగ్గర్లో తలదాచుకోండి."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f308bcf..994906b 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"สลับไปโหมดป้อนข้อความเพื่อป้อนเวลา"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"สลับไปโหมดนาฬิกาเพื่อป้อนเวลา"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ตัวเลือกในการป้อนอัตโนมัติ"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ไม่สามารถป้อนเนื้อหาอัตโนมัติ"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"บันทึกไปยัง <xliff:g id="LABEL">%1$s</xliff:g> ใช่ไหม"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"บันทึก <xliff:g id="TYPE">%1$s</xliff:g> ไปยัง <xliff:g id="LABEL">%2$s</xliff:g> ใช่ไหม"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"บันทึก"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"ไม่เป็นไร"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"รหัสผ่าน"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ที่อยู่"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"บัตรเครดิต"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ชื่อผู้ใช้"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ที่อยู่อีเมล"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"ทำใจให้สงบและหาที่กำบังในบริเวณใกล้เคียง"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"อพยพออกจากจากเขตชายฝั่งทะเลและบริเวณริมแม่น้ำไปยังสถานที่ที่ปลอดภัยกว่า เช่น ที่สูง โดยทันที"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ทำใจให้สงบและหาที่กำบังในบริเวณใกล้เคียง"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index fa02f8f..3e14b14 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Lumipat sa pamamaraan ng pag-input ng text para sa input na oras."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Lumipat sa mode ng orasan para sa input na oras."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Mga opsyon sa autofill"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Hindi maaaring ma-autofill ang mga content"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"I-save sa <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"I-save ang <xliff:g id="TYPE">%1$s</xliff:g> sa <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"I-save"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Hindi, salamat na lang"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"password"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"address"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"credit card"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"username"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"email address"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Manatiling kalmado at maghanap ng matutuluyan sa malapit."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Umalis kaagad sa mga baybayin at pampang, at pumunta sa isang mas ligtas na lokasyon tulad ng isang mataas na lugar."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Manatiling kalmado at maghanap ng matutuluyan sa malapit."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 4275e5c..da4ed4f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Zaman girişi için metin girişi moduna geçin."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Zaman girişi için saat moduna geçin."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Otomatik doldurma seçenekleri"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"İçerikler otomatik doldurulamıyor"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> hizmetine kaydedilsin mi?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g>, <xliff:g id="LABEL">%2$s</xliff:g> etkinliğine kaydedilsin mi?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Kaydet"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Hayır, teşekkürler"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"şifre"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"adres"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kredi kartı"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"kullanıcı adı"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-posta adresi"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Sakin olun ve yakınlarda sığınabileceğiniz bir yer bulun."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Kıyı kesimlerini ve nehir kenarlarını hemen boşaltarak yüksek yerler gibi daha güvenli bölgelere gidin."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sakin olun ve yakınlarda sığınabileceğiniz bir yer bulun."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 187904d..6c5846d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1794,19 +1794,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Перейти в текстовий режим, щоб ввести час."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Перейти в режим годинника, щоб ввести час."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Параметри автозаповнення"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Вміст не можна заповнити автоматично"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Зберегти в службі <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Зберегти дані (<xliff:g id="TYPE">%1$s</xliff:g>) у службі <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Зберегти дані (<xliff:g id="TYPE_0">%1$s</xliff:g> і <xliff:g id="TYPE_1">%2$s</xliff:g>) у службі <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Зберегти дані (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> і <xliff:g id="TYPE_2">%3$s</xliff:g>) у службі <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Зберегти"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Ні, дякую"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"пароль"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"адреса"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"кредитна картка"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"ім’я користувача"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"електронна адреса"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Не хвилюйтеся та знайдіть прихисток поблизу."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Негайно евакуюйтеся з прибережних районів і територій поблизу річок у безпечніше місце, як-от на територію на підвищенні."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Не хвилюйтеся та знайдіть прихисток поблизу."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index f87cf54..dcde3f6b 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -406,10 +406,8 @@
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"ایپ کو آلے کی فون والی خصوصیات تک رسائی حاصل کرنے کی اجازت دیتا ہے۔ یہ اجازت ایپ کو فون نمبر اور آلے کے IDs کا تعین کرنے، آیا کوئی کال فعال ہے، اور کال کے ذریعہ مربوط ریموٹ نمبر کا تعین کرنے دیتی ہے۔"</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"سسٹم کے ذریعہ کالز روٹ کریں"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"کالںگ کا تجربہ بہتر بنانے کے لیے سسٹم کے ذریعہ ایپ کو کالز روٹ کرنے کی اجازت دیتا ہے۔"</string>
- <!-- no translation found for permlab_readPhoneNumbers (6108163940932852440) -->
- <skip />
- <!-- no translation found for permdesc_readPhoneNumbers (8559488833662272354) -->
- <skip />
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"فون نمبرز پڑھیں"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"ایپ کو آلہ کے فون نمبرز تک رسائی کرنے دیتا ہے۔"</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ٹیبلیٹ کو سلیپ وضع میں جانے سے روکیں"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"TV کو سلیپ وضع میں جانے سے روکیں"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"فون کو سلیپ وضع میں جانے سے روکیں"</string>
@@ -1188,8 +1186,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> کو دیگر ایپس پر دکھایا کیا جا رہا ہے"</string>
- <!-- no translation found for alert_windows_notification_title (3697657294867638947) -->
- <skip />
+ <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="3367294525884949878">"آف کریں"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> تیار کیا جا رہا ہے"</string>
@@ -1736,19 +1733,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"وقت ان پٹ کے لیے ٹیکسٹ ان پٹ وضع پر سوئچ کریں۔"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"وقت ان پٹ کے لیے گھڑی وضع پر سوئچ کریں۔"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"آٹو فل کے اختیارات"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"موادوں کو آٹو فل نہیں کیا جا سکتا"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> میں محفوظ کریں؟"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> کو <xliff:g id="LABEL">%2$s</xliff:g> میں محفوظ کریں؟"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"محفوظ کریں"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"نہیں، شکریہ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"پاس ورڈ"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"پتہ"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"کریڈٹ کارڈ"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"صارف نام"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ای میل پتہ"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"پُرسکون رہیں اور قریبی پناہ حاصل کریں۔"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ساحلی خطوں اور دریائی کناروں کے علاقوں کو فوری طور پر خالی کر کے اونچے ٹیلے جیسے کسی زیادہ محفوظ مقام پر چلے جائیں۔"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"پُرسکون رہیں اور قریبی پناہ حاصل کریں۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index f841f1c..7592078 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1733,19 +1733,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Vaqtni kiritish uchun matn kiritish rejimiga o‘ting."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Vaqtni kiritish uchun soat rejimiga o‘ting."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Avtomatik to‘ldirish parametrlari"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Kontentlarni avtomatik to‘ldirib bo‘lmaydi"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> xizmatiga saqlansinmi?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="LABEL">%2$s</xliff:g> xizmatiga saqlansinmi?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ma’lumotlari <xliff:g id="LABEL">%3$s</xliff:g> yorlig‘iga saqlansinmi?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ma’lumotlari <xliff:g id="LABEL">%4$s</xliff:g> yorlig‘iga saqlansinmi?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Saqlash"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Yo‘q, kerak emas"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"parol"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"manzil"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kredit karta"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"foydalanuvchi nomi"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"e-pochta manzili"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Tinchlaning va yaqin-atrofdan boshpana qidiring."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Qirg‘oq va daryo bo‘ylaridan yuqori tepalik kabi xavfsiz joylarga darhol evakuatsiya qiling."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tinchlaning va yaqin-atrofdan boshpana qidiring."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ba72144..6b61b56 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Chuyển sang chế độ nhập văn bản để nhập thời gian."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Chuyển sang chế độ đồng hồ để nhập thời gian."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Tùy chọn tự động điền"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Không thể tự động điền nội dung"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Lưu vào <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Lưu <xliff:g id="TYPE">%1$s</xliff:g> vào <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"Lưu"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Không, cảm ơn"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"mật khẩu"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"địa chỉ"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"thẻ tín dụng"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"tên người dùng"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"địa chỉ email"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Hãy bình tĩnh và tìm kiếm nơi trú ẩn gần đó."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ngay lập tức sơ tán khỏi các vùng ven biển và khu vực ven sông để tới một nơi an toàn hơn như vùng đất cao."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hãy bình tĩnh và tìm kiếm nơi trú ẩn gần đó."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 8f110d1..0202a99 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"切换到文字输入模式来输入时间。"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"切换到时钟模式来输入时间。"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"自动填充选项"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"无法自动填充内容"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"要保存到<xliff:g id="LABEL">%1$s</xliff:g>吗?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"要将<xliff:g id="TYPE">%1$s</xliff:g>保存到<xliff:g id="LABEL">%2$s</xliff:g>吗?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"保存"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"不用了"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"密码"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"地址"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"信用卡"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"用户名"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"电子邮件地址"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"请保持冷静,并寻找附近的避难地点。"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"请立即从沿海和河滨区域撤离到高地等较安全的地方。"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"请保持冷静,并寻找附近的避难地点。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 556a5c7..da5c464 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1185,7 +1185,7 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"「<xliff:g id="NAME">%s</xliff:g>」目前在其他應用程式上顯示內容"</string>
- <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>目前在其他應用程式上層顯示內容"</string>
+ <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="3367294525884949878">"關閉"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"正在準備<xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"切換至文字輸入模式即可輸入時間。"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"切換至時鐘模式即可輸入時間。"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"自動填入選項"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"無法自動填入內容"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"要儲存至 <xliff:g id="LABEL">%1$s</xliff:g> 嗎?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"要將<xliff:g id="TYPE">%1$s</xliff:g>儲存至 <xliff:g id="LABEL">%2$s</xliff:g> 嗎?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"儲存"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"不用了,謝謝"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"密碼"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"地址"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"信用卡"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"使用者名稱"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"電郵地址"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"請保持冷靜,並尋找附近的避難所。"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"請立即從沿海和河岸地區撤離,前往高地等較安全的地點。"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"請保持冷靜,並尋找附近的避難所。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c16d59a..c7146a7 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1732,19 +1732,20 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"切換至文字輸入模式來輸入時間。"</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"切換至時鐘模式來輸入時間。"</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"自動填入選項"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"無法自動填入內容"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"要儲存到「<xliff:g id="LABEL">%1$s</xliff:g>」嗎?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"要將<xliff:g id="TYPE">%1$s</xliff:g>儲存到「<xliff:g id="LABEL">%2$s</xliff:g>」嗎?"</string>
+ <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
+ <skip />
+ <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
+ <skip />
<string name="autofill_save_yes" msgid="6398026094049005921">"儲存"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"不用了,謝謝"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"密碼"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"地址"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"信用卡"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"使用者名稱"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"電子郵件地址"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"請保持冷靜並尋找附近的避難地點。"</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"請立即從沿海與河岸地區撤離,前往高地這類較安全的地點。"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"請保持冷靜並尋找附近的避難地點。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e05aebf..5289834 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1732,19 +1732,18 @@
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Shintshela kumodi yokufaka umbhalo ngokufaka isikhathi."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Shintshela kumodi yewashi ngokufakwa kwesikhathi."</string>
<string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Izinketho zokugcwalisa ngokuzenzakalela"</string>
- <!-- no translation found for autofill_error_cannot_autofill (7402758580060110371) -->
- <skip />
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Okuqukethwe akukwazi ukugcwalisa ngokuzenzakalela"</string>
<string name="autofill_save_title" msgid="7081244500504163245">"Londoloza ku-<xliff:g id="LABEL">%1$s</xliff:g>?"</string>
<string name="autofill_save_title_with_type" msgid="4977385733042555659">"Londoloza i-<xliff:g id="TYPE">%1$s</xliff:g> ku-<xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Londoloza i-<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ku-<xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Londoloza i-<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ku-<xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"Londoloza"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"Cha ngiyabonga"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"iphasiwedi"</string>
<string name="autofill_save_type_address" msgid="4936707762193009542">"ikheli"</string>
<string name="autofill_save_type_credit_card" msgid="7127694776265563071">"ikhadi lesikweletu"</string>
- <!-- no translation found for autofill_save_type_username (239040540379769562) -->
- <skip />
- <!-- no translation found for autofill_save_type_email_address (5752949432129262174) -->
- <skip />
+ <string name="autofill_save_type_username" msgid="239040540379769562">"igama lomsebenzisi"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"ikheli le-imeyili"</string>
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Hlala ubeke umoya phansi uphinde ufune ukukhuselwa eduze."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Phuma ngokushesha kusukela kuzifunda ezingasolwandle nasezindaweni zemifula uye endaweni ephephile efana nendawo ephakeme."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hlala ubeke umoya phansi uphinde ufune ukukhuselwa eduze."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d26d952..5ede1c9 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2953,6 +2953,9 @@
See {@link android.view.View#setFocusedByDefault(boolean)}. -->
<attr name="focusedByDefault" format="boolean" />
+ <!-- Whether this View should use a default focus highlight when it gets focused but
+ doesn't have {@link android.R.attr#state_focused} defined in its background. -->
+ <attr name="defaultFocusHighlightEnabled" format="boolean" />
</declare-styleable>
<!-- Attributes that can be assigned to a tag for a particular View. -->
@@ -3214,18 +3217,7 @@
and subtype in order to provide the consistent user experience in switching
between IMEs and subtypes. -->
<attr name="supportsSwitchingToNextInputMethod" format="boolean" />
- <!-- Set to true if this input method supports ways to dismiss the windows assigned to
- the input method (for example, a dismiss button rendered by the input method itself). The
- System UI may optimize the UI by not showing system-level dismiss button if this
- value is true.
- <p> Must be a boolean value, either "true" or "false". The default value is "false".
- <p> This may also be a reference to a resource (in the form "@[package:]type:name")
- or theme attribute (in the form "?[package:]type:name") containing a value of this
- type.
- <p> A UI element that dismisses the input method window should report
- {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_DISMISS} action, so
- that accessibility services can handle it accordingly. -->
- <attr name="supportsDismissingWindow" format="boolean" />
+ <attr name="__removed2" format="boolean" />
</declare-styleable>
<!-- This is the subtype of InputMethod. Subtype can describe locales (for example, en_US and
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3dd7ad4..45dccb6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1881,10 +1881,6 @@
<!-- Amount of time in ms the user needs to press the relevant key to bring up the global actions dialog -->
<integer name="config_globalActionsKeyTimeout">500</integer>
- <!-- Default width of a vertical scrollbar and height of a horizontal scrollbar.
- Takes effect only if the scrollbar drawables have no intrinsic size. -->
- <dimen name="config_scrollbarSize">4dp</dimen>
-
<!-- Distance that should be scrolled, per axis value, in response to a horizontal
{@link MotionEvent#ACTION_SCROLL} event. -->
<dimen name="config_horizontalScrollFactor">64dp</dimen>
@@ -2798,7 +2794,7 @@
<string name="config_defaultCellBroadcastReceiverPkg" translatable="false">com.android.cellbroadcastreceiver</string>
<!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
- <string name="config_icon_mask" translatable="false">"M50,0L100,0 100,100 0,100 0,0z"</string>
+ <string name="config_icon_mask" translatable="false">"M50,0L92,0 A8,8,0,0 1 100,8 L100,92 A8,8,0,0 1 92,100 L8,100 A8,8,0,0 1 0,92 L 0,8 A8,8,0,0 1 8,0z"</string>
<!-- The component name, flattened to a string, for the default accessibility service to be
enabled by the accessibility shortcut. This service must be trusted, as it can be activated
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1d1fd5e..c3f8846b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2785,7 +2785,7 @@
<public name="focusedByDefault" />
<public name="appCategory" />
<public name="autoSizeMaxTextSize" />
- <public name="supportsDismissingWindow" />
+ <public name="__removed2" />
<public name="restartOnConfigChanges" />
<public name="certDigest" />
<public name="splitName" />
@@ -2814,6 +2814,7 @@
<public name="iconTintMode" />
<public name="maxAspectRatio"/>
<public name="iconSpaceReserved"/>
+ <public name="defaultFocusHighlightEnabled" />
</public-group>
<public-group type="style" first-id="0x010302e0">
@@ -2829,6 +2830,10 @@
<public name="autofilled_highlight" />
</public-group>
+ <public-group type="string" first-id="0x01040019">
+ <public name="paste_as_plain_text" />
+ </public-group>
+
<!-- ===============================================================
DO NOT ADD UN-GROUPED ITEMS HERE
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 7dac18d..2ae2ca0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -322,6 +322,7 @@
<item name="scrollbars">vertical</item>
<item name="fadingEdge">vertical</item>
<item name="fastScrollStyle">?attr/fastScrollStyle</item>
+ <item name="defaultFocusHighlightEnabled">false</item>
</style>
<style name="Widget.GestureOverlayView">
@@ -538,6 +539,7 @@
<item name="gravity">center_vertical</item>
<item name="breakStrategy">simple</item>
<item name="hyphenationFrequency">normal</item>
+ <item name="defaultFocusHighlightEnabled">false</item>
</style>
<style name="Widget.ExpandableListView" parent="Widget.ListView">
@@ -1482,4 +1484,10 @@
<item name="successColor">@color/lock_pattern_view_success_color</item>
</style>
+ <!-- @hide -->
+ <style name="AutofillDatasetPicker">
+ <item name="elevation">4dp</item>
+ <item name="background">@drawable/autofill_dataset_picker_background</item>
+ </style>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7cb9ba8..44a4af7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -434,7 +434,6 @@
<java-symbol type="dimen" name="config_viewConfigurationTouchSlop" />
<java-symbol type="dimen" name="config_viewMinFlingVelocity" />
<java-symbol type="dimen" name="config_viewMaxFlingVelocity" />
- <java-symbol type="dimen" name="config_scrollbarSize" />
<java-symbol type="dimen" name="config_horizontalScrollFactor" />
<java-symbol type="dimen" name="config_verticalScrollFactor" />
<java-symbol type="dimen" name="config_scrollFactor" />
@@ -2866,10 +2865,9 @@
<java-symbol type="dimen" name="item_touch_helper_swipe_escape_max_velocity"/>
<!-- com.android.server.autofill -->
- <!-- TODO: floating_window_z temporary exposed until Autofill UI uses a ContextThemeWrapper -->
- <java-symbol type="dimen" name="floating_window_z" />
<java-symbol type="layout" name="autofill_save"/>
<java-symbol type="layout" name="autofill_dataset_picker"/>
+ <java-symbol type="id" name="autofill_dataset_list"/>
<java-symbol type="id" name="autofill" />
<java-symbol type="id" name="autofill_save_title" />
<java-symbol type="id" name="autofill_save_subtitle" />
@@ -2890,6 +2888,8 @@
<java-symbol type="string" name="autofill_save_type_credit_card" />
<java-symbol type="string" name="autofill_save_type_username" />
<java-symbol type="string" name="autofill_save_type_email_address" />
+ <java-symbol type="drawable" name="autofill_dataset_picker_background" />
+ <java-symbol type="style" name="AutofillDatasetPicker" />
<!-- Accessibility fingerprint gestures -->
<java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 9911d9d..e0b4ec5 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -748,12 +748,12 @@
<!-- @hide DeviceDefault theme for a window that should use Settings theme colors
but has a full dark palette. ONLY USED FOR QUICK SETTINGS THEME -->
- <style name="Theme.DeviceDefault.QuickSettings" parent="Theme.Material">
+ <style name="Theme.DeviceDefault.QuickSettings" parent="Theme.DeviceDefault.Light">
<!-- Color palette -->
- <item name="colorPrimary">@color/primary_device_default_settings</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
- <item name="colorSecondary">@color/secondary_device_default_settings</item>
- <item name="colorAccent">@color/accent_device_default_dark</item>
+ <item name="colorPrimary">@color/primary_device_default_settings_light</item>
+ <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
+ <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
+ <item name="colorAccent">@color/accent_device_default_light</item>
<item name="colorControlNormal">?attr/textColorPrimary</item>
</style>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 9dafa7a..86abe97 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -214,7 +214,7 @@
<!-- Scrollbar attributes -->
<item name="scrollbarFadeDuration">250</item>
<item name="scrollbarDefaultDelayBeforeFade">400</item>
- <item name="scrollbarSize">@dimen/config_scrollbarSize</item>
+ <item name="scrollbarSize">10dp</item>
<item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_material</item>
<item name="scrollbarThumbVertical">@drawable/config_scrollbarThumbVertical</item>
<item name="scrollbarTrackHorizontal">@null</item>
@@ -582,7 +582,7 @@
<!-- Scrollbar attributes -->
<item name="scrollbarFadeDuration">250</item>
<item name="scrollbarDefaultDelayBeforeFade">400</item>
- <item name="scrollbarSize">@dimen/config_scrollbarSize</item>
+ <item name="scrollbarSize">10dp</item>
<item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_material</item>
<item name="scrollbarThumbVertical">@drawable/config_scrollbarThumbVertical</item>
<item name="scrollbarTrackHorizontal">@null</item>
diff --git a/core/tests/coretests/res/xml/ime_meta_dismiss.xml b/core/tests/coretests/res/xml/ime_meta_dismiss.xml
deleted file mode 100644
index 59f8ecc..0000000
--- a/core/tests/coretests/res/xml/ime_meta_dismiss.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<input-method
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:settingsActivity="com.android.inputmethod.latin.settings.SettingsActivity"
- android:supportsDismissingWindow="true"
->
- <subtype
- android:label="subtype1"
- android:imeSubtypeLocale="en_US"
- android:imeSubtypeMode="keyboard" />
-</input-method>
diff --git a/core/tests/coretests/src/android/provider/FontsContractTest.java b/core/tests/coretests/src/android/provider/FontsContractTest.java
index 1dd3ef6..ccc8c18 100644
--- a/core/tests/coretests/src/android/provider/FontsContractTest.java
+++ b/core/tests/coretests/src/android/provider/FontsContractTest.java
@@ -17,29 +17,29 @@
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import static android.provider.FontsContract.Columns.RESULT_CODE_OK;
+import static android.provider.FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND;
+import static android.provider.FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE;
+import static android.provider.FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY;
+
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.Signature;
import android.database.MatrixCursor;
-import android.graphics.Typeface;
import android.graphics.fonts.FontRequest;
-import android.graphics.fonts.FontResult;
-import android.os.Bundle;
-import android.os.ResultReceiver;
+import android.graphics.fonts.FontVariationAxis.InvalidFormatException;
+import android.graphics.fonts.FontVariationAxis;
+import android.provider.FontsContract.FontInfo;
import android.support.test.filters.SmallTest;
import android.test.ProviderTestCase2;
import android.util.Base64;
-import org.mockito.ArgumentCaptor;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -61,8 +61,6 @@
private final FontRequest request = new FontRequest(
TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query");
private TestFontsProvider mProvider;
- private FontsContract mContract;
- private ResultReceiver mResultReceiver;
private PackageManager mPackageManager;
public FontsContractTest() {
@@ -74,126 +72,178 @@
mProvider = getProvider();
mPackageManager = mock(PackageManager.class);
- mContract = new FontsContract(getMockContext(), mPackageManager);
- mResultReceiver = mock(ResultReceiver.class);
}
- public void testGetFontFromProvider_resultOK() {
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
-
- final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
- verify(mResultReceiver).send(
- eq(FontsContract.Columns.RESULT_CODE_OK), bundleCaptor.capture());
-
- Bundle bundle = bundleCaptor.getValue();
- assertNotNull(bundle);
- List<FontResult> resultList =
- bundle.getParcelableArrayList(FontsContract.PARCEL_FONT_RESULTS);
- assertNotNull(resultList);
- assertEquals(1, resultList.size());
- FontResult fontResult = resultList.get(0);
- assertEquals(TestFontsProvider.TTC_INDEX, fontResult.getTtcIndex());
- assertEquals(TestFontsProvider.VARIATION_SETTINGS, fontResult.getFontVariationSettings());
- assertEquals(TestFontsProvider.NORMAL_WEIGHT, fontResult.getWeight());
- assertEquals(TestFontsProvider.ITALIC, fontResult.getItalic());
- assertNotNull(fontResult.getFileDescriptor());
+ public void testGetFontFromProvider_resultOK() throws InvalidFormatException {
+ FontInfo[] fonts = FontsContract.getFontFromProvider(
+ getMockContext(), request, TestFontsProvider.AUTHORITY, null);
+ assertNotNull(fonts);
+ assertEquals(1, fonts.length);
+ FontInfo font = fonts[0];
+ assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex());
+ FontVariationAxis[] actual = font.getAxes();
+ assertEquals(1, actual.length);
+ assertEquals("wdth", actual[0].getTag());
+ assertEquals(1.0f, actual[0].getStyleValue(), 0);
+ assertEquals(TestFontsProvider.NORMAL_WEIGHT, font.getWeight());
+ assertEquals(TestFontsProvider.ITALIC, font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_OK, font.getResultCode());
}
- public void testGetFontFromProvider_providerDoesntReturnAllFields() {
+ public void testGetFontFromProvider_providerDoesntReturnAllFields()
+ throws InvalidFormatException {
mProvider.setReturnAllFields(false);
- final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
- verify(mResultReceiver).send(
- eq(FontsContract.Columns.RESULT_CODE_OK), bundleCaptor.capture());
-
- Bundle bundle = bundleCaptor.getValue();
- assertNotNull(bundle);
- List<FontResult> resultList =
- bundle.getParcelableArrayList(FontsContract.PARCEL_FONT_RESULTS);
- assertNotNull(resultList);
- assertEquals(1, resultList.size());
- FontResult fontResult = resultList.get(0);
- assertEquals(0, fontResult.getTtcIndex());
- assertNull(fontResult.getFontVariationSettings());
- assertEquals(400, fontResult.getWeight());
- assertFalse(fontResult.getItalic());
- assertNotNull(fontResult.getFileDescriptor());
+ FontInfo[] fonts = FontsContract.getFontFromProvider(
+ getMockContext(), request, TestFontsProvider.AUTHORITY, null);
+ assertNotNull(fonts);
+ assertEquals(1, fonts.length);
+ FontInfo font = fonts[0];
+ assertEquals(0, font.getTtcIndex());
+ assertNull(font.getAxes());
+ assertEquals(400, font.getWeight());
+ assertFalse(font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_OK, font.getResultCode());
}
- public void testGetFontFromProvider_resultFontNotFound() {
+ public void testGetFontFromProvider_resultFontNotFound() throws InvalidFormatException {
// Make the provider return unknown
- mProvider.setResultCode(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND);
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
-
- verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND,null);
+ mProvider.setResultCode(RESULT_CODE_FONT_NOT_FOUND);
+ FontInfo[] fonts = FontsContract.getFontFromProvider(
+ getMockContext(), request, TestFontsProvider.AUTHORITY, null);
+ assertNotNull(fonts);
+ assertEquals(1, fonts.length);
+ FontInfo font = fonts[0];
+ assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode());
}
- public void testGetFontFromProvider_resultFontUnavailable() {
+ public void testGetFontFromProvider_resultFontUnavailable() throws InvalidFormatException {
// Make the provider return font unavailable
- mProvider.setResultCode(FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE);
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+ mProvider.setResultCode(RESULT_CODE_FONT_UNAVAILABLE);
+ FontInfo[] fonts = FontsContract.getFontFromProvider(
+ getMockContext(), request, TestFontsProvider.AUTHORITY, null);
- verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE,null);
+ assertNotNull(fonts);
+ assertEquals(1, fonts.length);
+ FontInfo font = fonts[0];
+ assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex());
+ FontVariationAxis[] actual = font.getAxes();
+ assertEquals(1, actual.length);
+ assertEquals("wdth", actual[0].getTag());
+ assertEquals(1.0f, actual[0].getStyleValue(), 0);
+ assertEquals(TestFontsProvider.NORMAL_WEIGHT, font.getWeight());
+ assertEquals(TestFontsProvider.ITALIC, font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_FONT_UNAVAILABLE, font.getResultCode());
}
- public void testGetFontFromProvider_resultMalformedQuery() {
+ public void testGetFontFromProvider_resultMalformedQuery() throws InvalidFormatException {
// Make the provider return font unavailable
- mProvider.setResultCode(FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY);
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+ mProvider.setResultCode(RESULT_CODE_MALFORMED_QUERY);
+ FontInfo[] fonts = FontsContract.getFontFromProvider(
+ getMockContext(), request, TestFontsProvider.AUTHORITY, null);
- verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY,null);
+ assertNotNull(fonts);
+ assertEquals(1, fonts.length);
+ FontInfo font = fonts[0];
+ assertEquals(TestFontsProvider.TTC_INDEX, font.getTtcIndex());
+ FontVariationAxis[] actual = font.getAxes();
+ assertEquals(1, actual.length);
+ assertEquals("wdth", actual[0].getTag());
+ assertEquals(1.0f, actual[0].getStyleValue(), 0);
+ assertEquals(TestFontsProvider.NORMAL_WEIGHT, font.getWeight());
+ assertEquals(TestFontsProvider.ITALIC, font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_MALFORMED_QUERY, font.getResultCode());
}
- public void testGetFontFromProvider_resultFontNotFoundSecondRow() {
+ public void testGetFontFromProvider_resultFontNotFoundSecondRow()
+ throws InvalidFormatException {
MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC,
FontsContract.Columns.RESULT_CODE });
- cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
+ cursor.addRow(new Object[] { 1, 0, null, 400, 0, RESULT_CODE_OK});
cursor.addRow(new Object[] { 1, 0, null, 400, 0,
- FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND});
+ RESULT_CODE_FONT_NOT_FOUND});
mProvider.setCustomCursor(cursor);
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+ FontInfo[] fonts = FontsContract.getFontFromProvider(
+ getMockContext(), request, TestFontsProvider.AUTHORITY, null);
- verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
+ assertNotNull(fonts);
+ assertEquals(2, fonts.length);
+
+ FontInfo font = fonts[0];
+ assertEquals(0, font.getTtcIndex());
+ assertNull(font.getAxes());
+ assertEquals(400, font.getWeight());
+ assertFalse(font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_OK, font.getResultCode());
+
+ font = fonts[1];
+ assertEquals(0, font.getTtcIndex());
+ assertNull(font.getAxes());
+ assertEquals(400, font.getWeight());
+ assertFalse(font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode());
}
- public void testGetFontFromProvider_resultFontNotFoundOtherRow() {
+ public void testGetFontFromProvider_resultFontNotFoundOtherRow() throws InvalidFormatException {
MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC,
FontsContract.Columns.RESULT_CODE });
- cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
+ cursor.addRow(new Object[] { 1, 0, null, 400, 0, RESULT_CODE_OK});
cursor.addRow(new Object[] { 1, 0, null, 400, 0,
- FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND});
- cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
+ RESULT_CODE_FONT_NOT_FOUND});
+ cursor.addRow(new Object[] { 1, 0, null, 400, 0, RESULT_CODE_OK});
mProvider.setCustomCursor(cursor);
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+ FontInfo[] fonts = FontsContract.getFontFromProvider(
+ getMockContext(), request, TestFontsProvider.AUTHORITY, null);
- verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
- }
+ assertNotNull(fonts);
+ assertEquals(3, fonts.length);
- public void testGetFontFromProvider_resultCodeIsNegativeNumber() {
- MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
- FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
- FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC,
- FontsContract.Columns.RESULT_CODE });
- cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
- cursor.addRow(new Object[] { 1, 0, null, 400, 0, -5});
- mProvider.setCustomCursor(cursor);
- mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+ FontInfo font = fonts[0];
+ assertEquals(0, font.getTtcIndex());
+ assertNull(font.getAxes());
+ assertEquals(400, font.getWeight());
+ assertFalse(font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_OK, font.getResultCode());
- verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
+ font = fonts[1];
+ assertEquals(0, font.getTtcIndex());
+ assertNull(font.getAxes());
+ assertEquals(400, font.getWeight());
+ assertFalse(font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_FONT_NOT_FOUND, font.getResultCode());
+
+ font = fonts[2];
+ assertEquals(0, font.getTtcIndex());
+ assertNull(font.getAxes());
+ assertEquals(400, font.getWeight());
+ assertFalse(font.isItalic());
+ assertNotNull(font.getUri());
+ assertEquals(RESULT_CODE_OK, font.getResultCode());
}
public void testGetProvider_providerNotFound() {
when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(null);
- ProviderInfo result = mContract.getProvider(request, mResultReceiver);
-
- verify(mResultReceiver).send(FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND, null);
- assertNull(result);
+ try {
+ FontsContract.getProvider(mPackageManager, request);
+ fail();
+ } catch (NameNotFoundException e) {
+ // pass
+ }
}
public void testGetProvider_providerIsSystemApp() throws PackageManager.NameNotFoundException {
@@ -201,9 +251,7 @@
info.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info);
- ProviderInfo result = mContract.getProvider(request, mResultReceiver);
-
- verifyZeroInteractions(mResultReceiver);
+ ProviderInfo result = FontsContract.getProvider(mPackageManager, request);
assertEquals(info, result);
}
@@ -213,23 +261,22 @@
info.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info);
- ProviderInfo result = mContract.getProvider(
- new FontRequest(TestFontsProvider.AUTHORITY, "com.wrong.package", "query"),
- mResultReceiver);
+ try {
+ FontsContract.getProvider(
+ mPackageManager,
+ new FontRequest(TestFontsProvider.AUTHORITY, "com.wrong.package", "query"));
+ fail();
+ } catch (NameNotFoundException e) {
+ // pass
+ }
- verify(mResultReceiver).send(FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND, null);
- assertNull(result);
}
public void testGetProvider_providerIsNonSystemAppNoCerts()
throws PackageManager.NameNotFoundException {
setupPackageManager();
- // The default request is missing the certificates info.
- ProviderInfo result = mContract.getProvider(request, mResultReceiver);
-
- verify(mResultReceiver).send(FontsContract.RESULT_CODE_WRONG_CERTIFICATES, null);
- assertNull(result);
+ assertNull(FontsContract.getProvider(mPackageManager, request));
}
public void testGetProvider_providerIsNonSystemAppWrongCerts()
@@ -240,10 +287,8 @@
List<byte[]> certList = Arrays.asList(wrongCert);
FontRequest requestWrongCerts = new FontRequest(
TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList));
- ProviderInfo result = mContract.getProvider(requestWrongCerts, mResultReceiver);
- verify(mResultReceiver).send(FontsContract.RESULT_CODE_WRONG_CERTIFICATES, null);
- assertNull(result);
+ assertNull(FontsContract.getProvider(mPackageManager, requestWrongCerts));
}
public void testGetProvider_providerIsNonSystemAppCorrectCerts()
@@ -253,9 +298,9 @@
List<byte[]> certList = Arrays.asList(BYTE_ARRAY);
FontRequest requestRightCerts = new FontRequest(
TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList));
- ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
+ ProviderInfo result = FontsContract.getProvider(
+ mPackageManager, requestRightCerts);
- verifyZeroInteractions(mResultReceiver);
assertEquals(info, result);
}
@@ -267,11 +312,7 @@
List<byte[]> certList = Arrays.asList(wrongCert, BYTE_ARRAY);
FontRequest requestRightCerts = new FontRequest(
TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList));
- ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
-
- // There is one too many certs, should fail as the set doesn't match.
- verify(mResultReceiver).send(FontsContract.RESULT_CODE_WRONG_CERTIFICATES, null);
- assertNull(result);
+ assertNull(FontsContract.getProvider(mPackageManager, requestRightCerts));
}
public void testGetProvider_providerIsNonSystemAppDuplicateCerts()
@@ -294,12 +335,7 @@
List<byte[]> certList = Arrays.asList(BYTE_ARRAY_2, BYTE_ARRAY_COPY);
FontRequest requestRightCerts = new FontRequest(
TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList));
- ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
-
- // The given list includes an extra cert and doesn't have a second copy of the cert like
- // the provider does, so it should have failed.
- verify(mResultReceiver).send(FontsContract.RESULT_CODE_WRONG_CERTIFICATES, null);
- assertNull(result);
+ assertNull(FontsContract.getProvider(mPackageManager, requestRightCerts));
}
public void testGetProvider_providerIsNonSystemAppCorrectCertsSeveralSets()
@@ -312,9 +348,8 @@
certList.add(Arrays.asList(BYTE_ARRAY));
FontRequest requestRightCerts = new FontRequest(
TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", certList);
- ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
+ ProviderInfo result = FontsContract.getProvider(mPackageManager, requestRightCerts);
- verifyZeroInteractions(mResultReceiver);
assertEquals(info, result);
}
@@ -326,10 +361,12 @@
certList.add(Arrays.asList(BYTE_ARRAY));
FontRequest requestRightCerts = new FontRequest(
TestFontsProvider.AUTHORITY, "com.wrong.package.name", "query", certList);
- ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
-
- verify(mResultReceiver).send(FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND, null);
- assertNull(result);
+ try {
+ FontsContract.getProvider(mPackageManager, requestRightCerts);
+ fail();
+ } catch (NameNotFoundException e) {
+ // pass
+ }
}
private ProviderInfo setupPackageManager()
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 782a50f..d7887d3 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -473,7 +473,7 @@
Settings.Secure.USER_SETUP_COMPLETE,
Settings.Secure.VOICE_INTERACTION_SERVICE,
Settings.Secure.VOICE_RECOGNITION_SERVICE,
- Settings.Secure.WEB_ACTION_ENABLED);
+ Settings.Secure.INSTANT_APPS_ENABLED);
@Test
public void systemSettingsBackedUpOrBlacklisted() {
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
index 23dc80f..13cef52 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
@@ -51,12 +51,10 @@
final InputMethodInfo imi = buildInputMethodForTest(R.xml.ime_meta);
assertThat(imi.supportsSwitchingToNextInputMethod(), is(false));
- assertThat(imi.supportsDismissingWindow(), is(false));
final InputMethodInfo clone = cloneViaParcel(imi);
assertThat(clone.supportsSwitchingToNextInputMethod(), is(false));
- assertThat(clone.supportsDismissingWindow(), is(false));
}
@Test
@@ -70,17 +68,6 @@
assertThat(clone.supportsSwitchingToNextInputMethod(), is(true));
}
- @Test
- public void testSupportsDismissingWindow() throws Exception {
- final InputMethodInfo imi = buildInputMethodForTest(R.xml.ime_meta_dismiss);
-
- assertThat(imi.supportsDismissingWindow(), is(true));
-
- final InputMethodInfo clone = cloneViaParcel(imi);
-
- assertThat(clone.supportsDismissingWindow(), is(true));
- }
-
private InputMethodInfo buildInputMethodForTest(final @XmlRes int metaDataRes)
throws Exception {
final Context context = InstrumentationRegistry.getContext();
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 7edab008..3029134 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -26,7 +26,6 @@
import static android.widget.espresso.TextViewActions.Handle;
import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
-import static android.widget.espresso.TextViewAssertions.handleIsOnLine;
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
import static android.widget.espresso.TextViewAssertions.hasSelection;
import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
@@ -448,26 +447,6 @@
onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn\nopqr"));
}
- public void testSelectionHandles_multiLine_japanese() throws Exception {
- final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
- final StringBuilder builder = new StringBuilder();
- for (int i = 0; i < 100; ++i) {
- builder.append("\u3042\u3044\u3046\u3048\u304A");
- onView(withId(R.id.textview)).perform(replaceText(builder.toString()));
- final int lineEnd = textView.getLayout().getLineEnd(0);
- if (lineEnd < builder.length()) {
- break;
- }
- }
- onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(3));
-
- final int lineEnd = textView.getLayout().getLineEnd(0);
- onHandleView(com.android.internal.R.id.selection_end_handle)
- .perform(dragHandle(textView, Handle.SELECTION_END, lineEnd, true, false));
- onHandleView(com.android.internal.R.id.selection_end_handle)
- .check(handleIsOnLine(textView, 0));
- }
-
public void testSelectionHandles_multiLine_rtl() throws Exception {
// Arabic text.
final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n"
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
index 1e88712..335d021 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
@@ -331,37 +331,15 @@
*/
public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex,
boolean primary) {
- return dragHandle(textView, handleType, endIndex, primary, true);
- }
-
- /**
- * Returns an action that tap then drags on the handle from the current position to endIndex on
- * the TextView.<br>
- * <br>
- * View constraints:
- * <ul>
- * <li>must be a TextView's drag-handle displayed on screen
- * <ul>
- *
- * @param textView TextView the handle is on
- * @param handleType Type of the handle
- * @param endIndex The index of the TextView's text to end the drag at
- * @param primary whether to use primary direction to get coordinate form index when endIndex is
- * at a direction boundary.
- * @param getNewLineStartPosOnLineBreak whether to use new line start coordinate on a line break
- * within a paragraph.
- */
- public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex,
- boolean primary, boolean getNewLineStartPosOnLineBreak) {
return actionWithAssertions(
new DragAction(
DragAction.Drag.TAP,
new CurrentHandleCoordinates(textView),
- new HandleCoordinates(textView, handleType, endIndex, primary,
- getNewLineStartPosOnLineBreak),
+ new HandleCoordinates(textView, handleType, endIndex, primary),
Press.FINGER,
Editor.HandleView.class));
}
+
/**
* A provider of the x, y coordinates of the handle dragging point.
*/
@@ -424,16 +402,13 @@
private final Handle mHandleType;
private final int mIndex;
private final boolean mPrimary;
- private final boolean mGetNewLineStartPosOnLineBreak;
private final String mActionDescription;
- public HandleCoordinates(TextView textView, Handle handleType, int index, boolean primary,
- boolean getNewLineStartPosOnLineBreak) {
+ public HandleCoordinates(TextView textView, Handle handleType, int index, boolean primary) {
mTextView = textView;
mHandleType = handleType;
mIndex = index;
mPrimary = primary;
- mGetNewLineStartPosOnLineBreak = getNewLineStartPosOnLineBreak;
mActionDescription = "Could not locate " + handleType.toString()
+ " handle that points text index: " + index
+ " (" + (primary ? "primary" : "secondary" ) + ")";
@@ -470,10 +445,9 @@
final float currentX = handleView.getHorizontal(layout, currentOffset);
final float currentY = layout.getLineTop(currentLine);
final float[] currentCoordinates =
- convertToScreenCoordinates(mTextView, currentX, currentY);
+ TextCoordinates.convertToScreenCoordinates(mTextView, currentX, currentY);
final float[] targetCoordinates =
- (new TextCoordinates(mIndex, mPrimary, mGetNewLineStartPosOnLineBreak))
- .calculateCoordinates(mTextView);
+ (new TextCoordinates(mIndex, mPrimary)).calculateCoordinates(mTextView);
final Rect bounds = new Rect();
view.getBoundsOnScreen(bounds);
final Rect visibleDisplayBounds = new Rect();
@@ -511,27 +485,23 @@
private final int mIndex;
private final boolean mPrimary;
- private final boolean mGetNewLineStartPosOnLineBreak;
private final String mActionDescription;
public TextCoordinates(int index) {
- this(index, true, true);
+ this(index, true);
}
- public TextCoordinates(int index, boolean primary, boolean getNewLineStartPosOnLineBreak) {
+ public TextCoordinates(int index, boolean primary) {
mIndex = index;
mPrimary = primary;
- mGetNewLineStartPosOnLineBreak = getNewLineStartPosOnLineBreak;
mActionDescription = "Could not locate text at index: " + mIndex
- + " (" + (primary ? "primary" : "secondary" )
- + ", mGetNewLineStartPosOnLineBreak: " + mGetNewLineStartPosOnLineBreak + ")";
+ + " (" + (primary ? "primary" : "secondary" ) + ")";
}
@Override
public float[] calculateCoordinates(View view) {
try {
- return locateTextAtIndex((TextView) view, mIndex, mPrimary,
- mGetNewLineStartPosOnLineBreak);
+ return locateTextAtIndex((TextView) view, mIndex, mPrimary);
} catch (ClassCastException e) {
throw new PerformException.Builder()
.withActionDescription(mActionDescription)
@@ -550,38 +520,30 @@
/**
* @throws StringIndexOutOfBoundsException
*/
- private float[] locateTextAtIndex(TextView textView, int index, boolean primary,
- boolean getNewLineStartPosOnLineBreak) {
+ private float[] locateTextAtIndex(TextView textView, int index, boolean primary) {
if (index < 0 || index > textView.getText().length()) {
throw new StringIndexOutOfBoundsException(index);
}
final Layout layout = textView.getLayout();
-
- int line = layout.getLineForOffset(index);
- if (!getNewLineStartPosOnLineBreak && line > 0 && layout.getLineStart(line) == index
- && textView.getText().charAt(index - 1) != '\n') {
- line = line - 1;
- }
+ final int line = layout.getLineForOffset(index);
return convertToScreenCoordinates(textView,
- (primary ? layout.getPrimaryHorizontal(index, false,
- getNewLineStartPosOnLineBreak)
- : layout.getSecondaryHorizontal(index, false,
- getNewLineStartPosOnLineBreak)),
+ (primary ? layout.getPrimaryHorizontal(index)
+ : layout.getSecondaryHorizontal(index)),
layout.getLineTop(line));
}
- }
- /**
- * Convert TextView's local coordinates to on screen coordinates.
- * @param textView the TextView
- * @param x local horizontal coordinate
- * @param y local vertical coordinate
- * @return
- */
- public static float[] convertToScreenCoordinates(TextView textView, float x, float y) {
- final int[] xy = new int[2];
- textView.getLocationOnScreen(xy);
- return new float[]{ x + textView.getTotalPaddingLeft() - textView.getScrollX() + xy[0],
- y + textView.getTotalPaddingTop() - textView.getScrollY() + xy[1] };
+ /**
+ * Convert TextView's local coordinates to on screen coordinates.
+ * @param textView the TextView
+ * @param x local horizontal coordinate
+ * @param y local vertical coordinate
+ * @return
+ */
+ public static float[] convertToScreenCoordinates(TextView textView, float x, float y) {
+ final int[] xy = new int[2];
+ textView.getLocationOnScreen(xy);
+ return new float[]{ x + textView.getTotalPaddingLeft() - textView.getScrollX() + xy[0],
+ y + textView.getTotalPaddingTop() - textView.getScrollY() + xy[1] };
+ }
}
}
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java b/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
index fef84f4..6e44cd8 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
@@ -28,14 +28,11 @@
import android.support.test.espresso.ViewAssertion;
import android.view.View;
import android.widget.EditText;
-import android.widget.Editor;
import android.widget.TextView;
import junit.framework.AssertionFailedError;
import org.hamcrest.Matcher;
-import com.android.ex.editstyledtext.EditStyledText.EditModeActions.TextViewAction;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -140,14 +137,6 @@
}
/**
- * Returns a {@link ViewAssertion} that asserts that the TextView selection handle is on the
- * specified line.
- */
- public static ViewAssertion handleIsOnLine(TextView tv, int line) {
- return new SelectionHandlePositionAssertion(tv, line);
- }
-
- /**
* A {@link ViewAssertion} to check the selected text in a {@link TextView}.
*/
private static final class TextSelectionAssertion implements ViewAssertion {
@@ -227,31 +216,4 @@
closeTo(0f, 1f));
}
}
- /**
- * {@link ViewAssertion} to check that TextView selection handle is on a given line.
- */
- static class SelectionHandlePositionAssertion implements ViewAssertion {
- private TextView mTextView;
- private int mLine;
- private SelectionHandlePositionAssertion(TextView tv, int line) {
- mTextView = tv;
- mLine = line;
- }
-
- @Override
- public void check(View view, NoMatchingViewException exception) {
- if (!(view instanceof Editor.HandleView)) {
- throw new AssertionFailedError("View should be an instance of Editor.HandleView");
- }
- final Editor.HandleView handleView = (Editor.HandleView) view;
- final Rect bounds = new Rect();
- handleView.getBoundsOnScreen(bounds);
- final float bottom = mTextView.getLayout().getLineBottom(mLine);
- final float[] pos =
- TextViewActions.convertToScreenCoordinates(mTextView, 0, bottom);
-
- assertThat("Cursor should be on the line " + mLine, Double.valueOf(bounds.top),
- closeTo(pos[1], 1f));
- }
- }
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 1080a9f..1859378 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -154,22 +154,6 @@
}
@Test
- public void reportChooserSelection() throws InterruptedException {
- Intent sendIntent = createSendImageIntent();
- final ChooserWrapperActivity activity = mActivityRule
- .launchActivity(Intent.createChooser(sendIntent, null));
- waitForIdle();
- UsageStatsManager usm = activity.getUsageStatsManager();
- String packageName = "test_package";
- String action = "test_action";
- String annotation = "test_annotation";
- long beforeReport = getCount(usm, packageName, action, annotation);
- usm.reportChooserSelection(packageName, activity.getUserId(), annotation, null, action);
- long afterReport = getCount(usm, packageName, action, annotation);
- assertThat(afterReport, is(beforeReport + 1l));
- }
-
- @Test
public void noResultsFromPackageManager() {
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -356,19 +340,4 @@
private void waitForIdle() {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
-
- private Integer getCount(
- UsageStatsManager usm, String packageName, String action, String annotation) {
- if (usm == null) {
- return 0;
- }
- Map<String, UsageStats> stats =
- usm.queryAndAggregateUsageStats(Long.MIN_VALUE, Long.MAX_VALUE);
- UsageStats packageStats = stats.get(packageName);
- if (packageStats == null || packageStats.mChooserCounts == null
- || packageStats.mChooserCounts.get(action) == null) {
- return 0;
- }
- return packageStats.mChooserCounts.get(action).getOrDefault(annotation, 0);
- }
}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
new file mode 100644
index 0000000..284ab60
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+import android.app.usage.IUsageStatsManager;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArrayMap;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * ResolverListController Test.
+ */
+@RunWith(AndroidJUnit4.class)
+public class ResolverListControllerTest {
+
+ @Mock private Context mMockContext;
+ @Mock private PackageManager mMockPackageManager;
+ @Mock private Resources mMockResources;
+ @Mock private IUsageStatsManager mMockService;
+
+ private ResolverListController mController;
+ private UsageStatsManager mUsm;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ Configuration config = new Configuration();
+ config.locale = Locale.getDefault();
+ List<ResolveInfo> services = new ArrayList<>();
+ when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(services);
+ when(mMockResources.getConfiguration()).thenReturn(config);
+ when(mMockContext.getResources()).thenReturn(mMockResources);
+ when(mMockContext.getPackageName()).thenReturn("android");
+ when(mMockContext.getUserId()).thenReturn(54321);
+ when(mMockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(null);
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+ }
+
+ @Test
+ public void reportChooserSelection() throws InterruptedException, RemoteException {
+ String annotation = "test_annotation";
+ Intent sendIntent = createSendImageIntent(annotation);
+ String refererPackage = "test_referer_package";
+ String packageName = "test_package";
+ String action = "test_action";
+ final int initialCount = 1234;
+ UsageStats packageStats = initStats(packageName, action, annotation, initialCount);
+ UsageStats oneClickStats = initStats(packageName, action, annotation, 1);
+ final List<UsageStats> slices = new ArrayList<>();
+ slices.add(packageStats);
+ ParceledListSlice<UsageStats> stats = new ParceledListSlice<>(slices);
+ when(mMockService.queryUsageStats(anyInt(), anyLong(), anyLong(), anyString()))
+ .thenReturn(stats);
+ Answer<Void> answer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ slices.add(oneClickStats);
+ return null;
+ }
+ };
+ doAnswer(answer).when(mMockService).reportChooserSelection(
+ anyString(), anyInt(), anyString(), any(), anyString());
+ when(mMockContext.getOpPackageName()).thenReturn(refererPackage);
+ mUsm = new UsageStatsManager(mMockContext, mMockService);
+ when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm);
+ mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent,
+ refererPackage, UserHandle.USER_CURRENT);
+ mController.sort(new ArrayList<ResolverActivity.ResolvedComponentInfo>());
+ long beforeReport = getCount(mUsm, packageName, action, annotation);
+ mController.updateChooserCounts(packageName, UserHandle.USER_CURRENT, action);
+ long afterReport = getCount(mUsm, packageName, action, annotation);
+ assertThat(afterReport, is(beforeReport + 1l));
+ }
+
+ private UsageStats initStats(String packageName, String action,
+ String annotation, int count) {
+ ArrayMap<String, ArrayMap<String, Integer>> chooserCounts = new ArrayMap<>();
+ ArrayMap<String, Integer> counts = new ArrayMap<>();
+ counts.put(annotation, count);
+ chooserCounts.put(action, counts);
+ UsageStats packageStats = new UsageStats();
+ packageStats.mPackageName = packageName;
+ packageStats.mChooserCounts = chooserCounts;
+ return packageStats;
+ }
+
+ private Intent createSendImageIntent(String annotation) {
+ Intent sendIntent = new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
+ sendIntent.setType("image/jpeg");
+ ArrayList<String> annotations = new ArrayList<>();
+ annotations.add(annotation);
+ sendIntent.putStringArrayListExtra(Intent.EXTRA_CONTENT_ANNOTATIONS, annotations);
+ return sendIntent;
+ }
+
+ private Integer getCount(
+ UsageStatsManager usm, String packageName, String action, String annotation) {
+ if (usm == null) {
+ return 0;
+ }
+ Map<String, UsageStats> stats =
+ usm.queryAndAggregateUsageStats(Long.MIN_VALUE, Long.MAX_VALUE);
+ UsageStats packageStats = stats.get(packageName);
+ if (packageStats == null || packageStats.mChooserCounts == null
+ || packageStats.mChooserCounts.get(action) == null) {
+ return 0;
+ }
+ return packageStats.mChooserCounts.get(action).getOrDefault(annotation, 0);
+ }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index 686f75b..515e558 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -75,8 +75,7 @@
}
final InputMethodInfo imi = new InputMethodInfo(ri, DUMMY_IS_AUX_IME,
DUMMY_SETTING_ACTIVITY_NAME, subtypes, DUMMY_IS_DEFAULT_RES_ID,
- DUMMY_FORCE_DEFAULT, supportsSwitchingToNextInputMethod,
- false /* supportsDismissingWindow */);
+ DUMMY_FORCE_DEFAULT, supportsSwitchingToNextInputMethod);
if (subtypes == null) {
items.add(new ImeSubtypeListItem(imeName, null /* variableName */, imi,
NOT_A_SUBTYPE_ID, null, SYSTEM_LOCALE));
@@ -112,8 +111,7 @@
.build());
final InputMethodInfo imi = new InputMethodInfo(ri, DUMMY_IS_AUX_IME,
DUMMY_SETTING_ACTIVITY_NAME, subtypes, DUMMY_IS_DEFAULT_RES_ID,
- DUMMY_FORCE_DEFAULT, true /* supportsSwitchingToNextInputMethod */,
- false /* supportsDismissingWindow */);
+ DUMMY_FORCE_DEFAULT, true /* supportsSwitchingToNextInputMethod */);
return new ImeSubtypeListItem(imeName, subtypeName, imi, subtypeIndex, subtypeLocale,
systemLocale);
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 7289429..2a2e14b 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -157,10 +157,12 @@
/**
* Specify a bitmap for the canvas to draw into. All canvas state such as
- * layers, filters, and the save/restore stack are reset with the exception
- * of the current matrix and clip stack. Additionally, as a side-effect
+ * layers, filters, and the save/restore stack are reset. Additionally,
* the canvas' target density is updated to match that of the bitmap.
*
+ * Prior to API level {@value Build.VERSION_CODES#O} the current matrix and
+ * clip stack were preserved.
+ *
* @param bitmap Specifies a mutable bitmap for the canvas to draw into.
* @see #setDensity(int)
* @see #getDensity()
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 5afe5e9..21533f8 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -33,6 +33,8 @@
import android.graphics.fonts.FontRequest;
import android.graphics.fonts.FontResult;
import android.graphics.fonts.FontVariationAxis;
+import android.graphics.fonts.FontVariationAxis.InvalidFormatException;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
@@ -128,6 +130,15 @@
private int mStyle = 0;
+ // Value for weight and italic. Indicates the value is resolved by font metadata.
+ // Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
+ /** @hide */
+ public static final int RESOLVE_BY_FONT_TABLE = -1;
+
+ // Style value for building typeface.
+ private static final int STYLE_NORMAL = 0;
+ private static final int STYLE_ITALIC = 1;
+
private int[] mSupportedAxes;
private static final int[] EMPTY_AXES = {};
@@ -167,8 +178,8 @@
FontFamily fontFamily = new FontFamily();
// TODO: introduce ttc index and variation settings to resource type font.
if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */,
- 0 /* ttcIndex */, Builder.RESOLVE_BY_FONT_TABLE /* weight */,
- Builder.RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
+ 0 /* ttcIndex */, RESOLVE_BY_FONT_TABLE /* weight */,
+ RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
fontFamily.freeze();
FontFamily[] families = {fontFamily};
typeface = createFromFamiliesWithDefault(families);
@@ -225,8 +236,7 @@
for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
0 /* resourceCookie */, false /* isAsset */, 0 /* ttcIndex */,
- fontFile.getWeight(),
- fontFile.isItalic() ? Builder.ITALIC : Builder.NORMAL,
+ fontFile.getWeight(), fontFile.isItalic() ? STYLE_ITALIC : STYLE_NORMAL,
null /* axes */)) {
return null;
}
@@ -358,7 +368,7 @@
ByteBuffer fontBuffer = fileChannel.map(
FileChannel.MapMode.READ_ONLY, 0, fontSize);
int weight = result.getWeight();
- int italic = result.getItalic() ? Builder.ITALIC : Builder.NORMAL;
+ int italic = result.getItalic() ? STYLE_ITALIC : STYLE_NORMAL;
FontVariationAxis[] axes = null;
try {
axes = FontVariationAxis.fromFontVariationSettings(
@@ -468,55 +478,42 @@
/**
* A builder class for creating new Typeface instance.
*
+ * <p>
* Examples,
* 1) Create Typeface from ttf file.
* <pre>
* <code>
- * Typeface.Builder buidler = new Typeface.Builder.obtain();
- * builder.setSourceFromFilePath("your_font_file.ttf");
+ * Typeface.Builder buidler = new Typeface.Builder("your_font_file.ttf");
* Typeface typeface = builder.build();
- * builder.recycle();
* </code>
* </pre>
*
* 2) Create Typeface from ttc file in assets directory.
* <pre>
* <code>
- * Typeface.Builder buidler = new Typeface.Builder.obtain();
- * builder.setSourceFromAsset(getAssets(), "your_font_file.ttc");
- * builder.setTtcIndex(2); // set index of font collection.
+ * Typeface.Builder buidler = new Typeface.Builder(getAssets(), "your_font_file.ttc");
+ * builder.setTtcIndex(2); // Set index of font collection.
* Typeface typeface = builder.build();
- * builder.recycle();
* </code>
* </pre>
*
- * 3) Create Typeface from existing Typeface with variation settings.
+ * 3) Create Typeface with variation settings.
* <pre>
- *
- * <p>Note that only one source can be specified for the single Typeface.</p>
+ * <code>
+ * Typeface.Builder buidler = new Typeface.Builder("your_font_file.ttf");
+ * builder.setFontVariationSettings("'wght' 700, 'slnt' 20, 'ital' 1");
+ * builder.setWeight(700); // Tell the system that this is a bold font.
+ * builder.setItalic(true); // Tell the system that this is an italic style font.
+ * Typeface typeface = builder.build();
+ * </code>
+ * </pre>
+ * </p>
*/
public static final class Builder {
- /**
- * Value for weight and italic.
- *
- * Indicates the value is resolved by font metadata.
- */
- // Must be same with C++ constant in core/jni/android/graphics/FontFamily.cpp
- public static final int RESOLVE_BY_FONT_TABLE = -1;
-
- /**
- * Value for italic.
- *
- * Indicates the font style is not italic.
- */
- public static final int NORMAL = 0;
-
- /**
- * Value for italic.
- *
- * Indicates the font style is italic.
- */
- public static final int ITALIC = 1;
+ /** @hide */
+ public static final int NORMAL_WEIGHT = 400;
+ /** @hide */
+ public static final int BOLD_WEIGHT = 700;
private int mTtcIndex;
private FontVariationAxis[] mAxes;
@@ -524,134 +521,79 @@
private AssetManager mAssetManager;
private String mPath;
private FileDescriptor mFd;
- private @IntRange(from = -1) int mWeight = RESOLVE_BY_FONT_TABLE;
- /** @hide */
- @Retention(SOURCE)
- @IntDef({RESOLVE_BY_FONT_TABLE, NORMAL, ITALIC})
- public @interface Italic {}
- private @Italic int mItalic = RESOLVE_BY_FONT_TABLE;
+ private FontsContract.FontInfo[] mFonts;
+ private Map<Uri, ByteBuffer> mFontBuffers;
+ private String mFallbackFamilyName;
- private boolean mHasSourceSet = false;
- private boolean mRecycled = false;
-
- /** Use Builder.obtain() instead */
- private void Builder() {}
-
- private static AtomicReference<Builder> mCache = new AtomicReference<>();
+ private int mWeight = RESOLVE_BY_FONT_TABLE;
+ private int mItalic = RESOLVE_BY_FONT_TABLE;
/**
- * Returns Typeface.Builder from pool.
- */
- public static Builder obtain() {
- final Builder builder = mCache.getAndSet(null);
- if (builder != null) {
- builder.mRecycled = false;
- return builder;
- }
- return new Builder();
- }
-
- /**
- * Resets the internal states.
- */
- public void reset() {
- checkNotRecycled();
- mTtcIndex = 0;
- mAxes = null;
-
- mAssetManager = null;
- mPath = null;
- mFd = null;
-
- mWeight = RESOLVE_BY_FONT_TABLE;
- mItalic = RESOLVE_BY_FONT_TABLE;
-
- mHasSourceSet = false;
- }
-
- /**
- * Returns the instance to the pool.
- */
- public void recycle() {
- reset();
- mRecycled = true;
-
- mCache.compareAndSet(null, this);
- }
-
- private void checkNotRecycled() {
- if (mRecycled) {
- throw new IllegalStateException("Don't use Builder after calling recycle()");
- }
- }
-
- private void checkSingleFontSource() {
- if (mHasSourceSet) {
- throw new IllegalStateException("Typeface can only built with single font source.");
- }
- }
-
- /**
- * Sets a font file as a source of Typeface.
+ * Constructs a builder with a file path.
*
* @param path The file object refers to the font file.
*/
- public Builder setSourceFromFile(@NonNull File path) {
- return setSourceFromFilePath(path.getAbsolutePath());
+ public Builder(@NonNull File path) {
+ mPath = path.getAbsolutePath();
}
/**
- * Sets a font file as a source of Typeface.
+ * Constructs a builder with a file descriptor.
*
* @param fd The file descriptor. The passed fd must be mmap-able.
*/
- public Builder setSourceFromFile(@NonNull FileDescriptor fd) {
- checkNotRecycled();
- checkSingleFontSource();
+ public Builder(@NonNull FileDescriptor fd) {
mFd = fd;
- mHasSourceSet = true;
- return this;
}
/**
- * Sets a font file as a source of Typeface.
+ * Constructs a builder with a file path.
*
* @param path The full path to the font file.
*/
- public Builder setSourceFromFilePath(@NonNull String path) {
- checkNotRecycled();
- checkSingleFontSource();
+ public Builder(@NonNull String path) {
mPath = path;
- mHasSourceSet = true;
- return this;
}
/**
- * Sets an asset entry as a source of Typeface.
+ * Constructs a builder from an asset manager and a file path in an asset directory.
*
* @param assetManager The application's asset manager
* @param path The file name of the font data in the asset directory
*/
- public Builder setSourceFromAsset(@NonNull AssetManager assetManager,
- @NonNull String path) {
- checkNotRecycled();
- checkSingleFontSource();
+ public Builder(@NonNull AssetManager assetManager, @NonNull String path) {
mAssetManager = Preconditions.checkNotNull(assetManager);
mPath = Preconditions.checkStringNotEmpty(path);
- mHasSourceSet = true;
- return this;
+ }
+
+ /**
+ * Constracts a builder from an array of FontsContract.FontInfo.
+ *
+ * Since {@link FontsContract.FontInfo} holds information about TTC indices and
+ * variation settings, there is no need to call {@link #setTtcIndex} or
+ * {@link #setFontVariationSettings}. Similary, {@link FontsContract.FontInfo} holds
+ * weight and italic information, so {@link #setWeight} and {@link #setItalic} are used
+ * for style matching during font selection.
+ *
+ * @param results The array of {@link FontsContract.FontInfo}
+ * @param buffers The mapping from URI to buffers to be used during building.
+ * @hide
+ */
+ public Builder(@NonNull FontsContract.FontInfo[] fonts,
+ @NonNull Map<Uri, ByteBuffer> buffers) {
+ mFonts = fonts;
+ mFontBuffers = buffers;
}
/**
* Sets weight of the font.
*
- * By passing {@link #RESOLVE_BY_FONT_TABLE}, weight value is resolved by OS/2 table in
- * font file if possible.
- * @param weight a weight value or {@link #RESOLVE_BY_FONT_TABLE}
+ * Tells the system the weight of the given font. If not provided, the system will resolve
+ * the weight value by reading font tables.
+ * @param weight a weight value.
*/
- public Builder setWeight(@IntRange(from = -1) int weight) {
- checkNotRecycled();
+ public Builder setWeight(@IntRange(from = 1, to = 1000) int weight) {
mWeight = weight;
return this;
}
@@ -659,26 +601,27 @@
/**
* Sets italic information of the font.
*
- * By passing {@link #RESOLVE_BY_FONT_TABLE}, italic or normal is determined by OS/2 table
- * in font file if possible.
- * @param italic One of {@link #NORMAL}, {@link #ITALIC}, {@link #RESOLVE_BY_FONT_TABLE}.
- * will be used.
+ * Tells the system the style of the given font. If not provided, the system will resolve
+ * the style by reading font tables.
+ * @param italic {@code true} if the font is italic. Otherwise {@code false}.
*/
- public Builder setItalic(@Italic int italic) {
- checkNotRecycled();
- mItalic = italic;
+ public Builder setItalic(boolean italic) {
+ mItalic = italic ? STYLE_ITALIC : STYLE_NORMAL;
return this;
}
/**
- * Sets an idex of the font collection.
+ * Sets an index of the font collection.
*
* Can not be used for Typeface source. build() method will return null for invalid index.
* @param ttcIndex An index of the font collection. If the font source is not font
* collection, do not call this method or specify 0.
*/
public Builder setTtcIndex(@IntRange(from = 0) int ttcIndex) {
- checkNotRecycled();
+ if (mFonts != null) {
+ throw new IllegalArgumentException(
+ "TTC index can not be specified for FontResult source.");
+ }
mTtcIndex = ttcIndex;
return this;
}
@@ -687,12 +630,15 @@
* Sets a font variation settings.
*
* @param variationSettings See {@link android.widget.TextView#setFontVariationSettings}.
- * @throws FontVariationAxis.InvalidFormatException If given string is not a valid font
- * variation settings format.
+ * @throws InvalidFormatException If given string is not a valid font variation settings
+ * format.
*/
public Builder setFontVariationSettings(@Nullable String variationSettings)
- throws FontVariationAxis.InvalidFormatException {
- checkNotRecycled();
+ throws InvalidFormatException {
+ if (mFonts != null) {
+ throw new IllegalArgumentException(
+ "Font variation settings can not be specified for FontResult source.");
+ }
if (mAxes != null) {
throw new IllegalStateException("Font variation settings are already set.");
}
@@ -706,7 +652,10 @@
* @param axes An array of font variation axis tag-value pairs.
*/
public Builder setFontVariationSettings(@Nullable FontVariationAxis[] axes) {
- checkNotRecycled();
+ if (mFonts != null) {
+ throw new IllegalArgumentException(
+ "Font variation settings can not be specified for FontResult source.");
+ }
if (mAxes != null) {
throw new IllegalStateException("Font variation settings are already set.");
}
@@ -752,11 +701,6 @@
* @return Newly created Typeface. May return null if some parameters are invalid.
*/
public Typeface build() {
- checkNotRecycled();
- if (!mHasSourceSet) {
- return null;
- }
-
if (mFd != null) { // set source by setSourceFromFile(FileDescriptor)
try (FileInputStream fis = new FileInputStream(mFd)) {
FileChannel channel = fis.getChannel();
@@ -800,9 +744,36 @@
fontFamily.freeze();
FontFamily[] families = { fontFamily };
return createFromFamiliesWithDefault(families);
- } else {
- throw new IllegalArgumentException("No source was set.");
+ } else if (mFonts != null) {
+ final FontFamily fontFamily = new FontFamily();
+ boolean atLeastOneFont = false;
+ for (FontsContract.FontInfo font : mFonts) {
+ final ByteBuffer fontBuffer = mFontBuffers.get(font.getUri());
+ if (fontBuffer == null) {
+ continue; // skip
+ }
+ final boolean success = fontFamily.addFontFromBuffer(fontBuffer,
+ font.getTtcIndex(), font.getAxes(), font.getWeight(),
+ font.isItalic() ? STYLE_ITALIC : STYLE_NORMAL);
+ if (!success) {
+ fontFamily.abortCreation();
+ return null;
+ }
+ atLeastOneFont = true;
+ }
+ if (!atLeastOneFont) {
+ // No fonts are avaialble. No need to create new Typeface and returns fallback
+ // Typeface instead.
+ fontFamily.abortCreation();
+ return null;
+ }
+ fontFamily.freeze();
+ FontFamily[] families = { fontFamily };
+ return createFromFamiliesWithDefault(families);
}
+
+ // Must not reach here.
+ throw new IllegalArgumentException("No source was set.");
}
}
@@ -897,15 +868,9 @@
throw new NullPointerException(); // for backward compatibility
}
if (sFallbackFonts != null) {
- final Builder builder = Builder.obtain();
- try {
- builder.setSourceFromAsset(mgr, path);
- Typeface typeface = builder.build();
- if (typeface != null) {
- return typeface;
- }
- } finally {
- builder.recycle();
+ Typeface typeface = new Builder(mgr, path).build();
+ if (typeface != null) {
+ return typeface;
}
}
// For the compatibility reasons, throw runtime exception if failed to create Typeface.
@@ -949,17 +914,11 @@
throw new NullPointerException();
}
if (sFallbackFonts != null) {
- final Builder builder = Builder.obtain();
- try {
- builder.setSourceFromFilePath(path);
- Typeface typeface = builder.build();
- if (typeface != null) {
- // For the compatibility reasons, throw runtime exception if failed to create
- // Typeface.
- return typeface;
- }
- } finally {
- builder.recycle();
+ Typeface typeface = new Builder(path).build();
+ if (typeface != null) {
+ // For the compatibility reasons, throw runtime exception if failed to create
+ // Typeface.
+ return typeface;
}
}
throw new RuntimeException("Font not found " + path);
@@ -1023,7 +982,7 @@
}
}
if (!fontFamily.addFontFromBuffer(fontBuffer, font.getTtcIndex(), font.getAxes(),
- font.getWeight(), font.isItalic() ? Builder.ITALIC : Builder.NORMAL)) {
+ font.getWeight(), font.isItalic() ? STYLE_ITALIC : STYLE_NORMAL)) {
Log.e(TAG, "Error creating font " + fullPathName + "#" + font.getTtcIndex());
}
}
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 643c0da..6dfe03d 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -728,6 +728,12 @@
return mLayerState.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mLayerState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] state) {
boolean changed = false;
@@ -1035,6 +1041,17 @@
return isStateful;
}
+ public final boolean hasFocusStateSpecified() {
+ final ChildDrawable[] array = mChildren;
+ for (int i = 0; i < N_CHILDREN; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.hasFocusStateSpecified()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public final boolean canConstantState() {
final ChildDrawable[] array = mChildren;
for (int i = 0; i < N_CHILDREN; i++) {
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 6deeb0d..5004667 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -737,6 +737,12 @@
|| super.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mBitmapState.mTint != null && mBitmapState.mTint.hasFocusStateSpecified();
+ }
+
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 7524cac..559e3d3 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -207,6 +207,12 @@
return mColorState.mTint != null && mColorState.mTint.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mColorState.mTint != null && mColorState.mTint.hasFocusStateSpecified();
+ }
+
@Override
public int getOpacity() {
if (mTintFilter != null || mPaint.getColorFilter() != null) {
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 850f40e..44fb1c7 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -26,6 +26,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -713,6 +714,25 @@
}
/**
+ * Indicates whether this drawable has at least one state spec explicitly
+ * specifying {@link android.R.attr#state_focused}.
+ *
+ * <p>Note: A View uses a {@link Drawable} instance as its background and it
+ * changes its appearance based on a state. On keyboard devices, it should
+ * specify its {@link android.R.attr#state_focused} to make sure the user
+ * knows which view is holding the focus.</p>
+ *
+ * @return {@code true} if {@link android.R.attr#state_focused} is specified
+ * for this drawable.
+ *
+ * @hide
+ */
+ @TestApi
+ public boolean hasFocusStateSpecified() {
+ return false;
+ }
+
+ /**
* Specify a set of states for the drawable. These are use-case specific,
* so see the relevant documentation. As an example, the background for
* widgets like Button understand the following states:
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index a491d7e..aa4cd9c 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -242,6 +242,18 @@
return mDrawableContainerState.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ if (mCurrDrawable != null) {
+ return mCurrDrawable.hasFocusStateSpecified();
+ }
+ if (mLastDrawable != null) {
+ return mLastDrawable.hasFocusStateSpecified();
+ }
+ return false;
+ }
+
@Override
public void setAutoMirrored(boolean mirrored) {
if (mDrawableContainerState.mAutoMirrored != mirrored) {
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 5887939..431b63b 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -323,6 +323,12 @@
return mDrawable != null && mDrawable.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mDrawable != null && mDrawable.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] state) {
if (mDrawable != null && mDrawable.isStateful()) {
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 7aad7df..6c3aea2 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -987,6 +987,15 @@
|| (s.mTint != null && s.mTint.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ final GradientState s = mGradientState;
+ return (s.mSolidColors != null && s.mSolidColors.hasFocusStateSpecified())
+ || (s.mStrokeColors != null && s.mStrokeColors.hasFocusStateSpecified())
+ || (s.mTint != null && s.mTint.hasFocusStateSpecified());
+ }
+
@Override
public @Config int getChangingConfigurations() {
return super.getChangingConfigurations() | mGradientState.getChangingConfigurations();
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index b159f0f..4725c2c 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1476,6 +1476,12 @@
return mLayerState.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mLayerState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] state) {
boolean changed = false;
@@ -2117,6 +2123,18 @@
return isStateful;
}
+ public final boolean hasFocusStateSpecified() {
+ final int N = mNumChildren;
+ final ChildDrawable[] array = mChildren;
+ for (int i = 0; i < N; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.hasFocusStateSpecified()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public final boolean canConstantState() {
final ChildDrawable[] array = mChildren;
final int N = mNumChildren;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index c7183d9..1790020 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -574,6 +574,12 @@
return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mNinePatchState.mTint != null && mNinePatchState.mTint.hasFocusStateSpecified();
+ }
+
final static class NinePatchState extends ConstantState {
@Config int mChangingConfigurations;
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index f83c160..bfd0604 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -377,6 +377,12 @@
return true;
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return true;
+ }
+
/**
* Sets the ripple color.
*
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 6758607..c43899b 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -352,6 +352,12 @@
return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mShapeState.mTint != null && mShapeState.mTint.hasFocusStateSpecified();
+ }
+
/**
* Subclasses override this to parse custom subelements. If you handle it,
* return true, else return <em>super.inflateTag(...)</em>.
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 64a9eb5..c98f160 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -90,6 +90,12 @@
return true;
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mStateListState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] stateSet) {
final boolean changed = super.onStateChange(stateSet);
@@ -342,6 +348,10 @@
return -1;
}
+ boolean hasFocusStateSpecified() {
+ return StateSet.containsAttribute(mStateSets, R.attr.state_focused);
+ }
+
@Override
public Drawable newDrawable() {
return new StateListDrawable(this, null);
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index a1539b8..41e5af1 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -413,6 +413,12 @@
return super.isStateful() || (mVectorState != null && mVectorState.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mVectorState != null && mVectorState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] stateSet) {
boolean changed = false;
@@ -976,6 +982,11 @@
|| (mRootGroup != null && mRootGroup.isStateful());
}
+ public boolean hasFocusStateSpecified() {
+ return mTint != null && mTint.hasFocusStateSpecified()
+ || (mRootGroup != null && mRootGroup.hasFocusStateSpecified());
+ }
+
void setViewportSize(float viewportWidth, float viewportHeight) {
mViewportWidth = viewportWidth;
mViewportHeight = viewportHeight;
@@ -1326,6 +1337,21 @@
}
@Override
+ public boolean hasFocusStateSpecified() {
+ boolean result = false;
+
+ final ArrayList<VObject> children = mChildren;
+ for (int i = 0, count = children.size(); i < count; i++) {
+ final VObject child = children.get(i);
+ if (child.isStateful()) {
+ result |= child.hasFocusStateSpecified();
+ }
+ }
+
+ return result;
+ }
+
+ @Override
int getNativeSize() {
// Return the native allocation needed for the subtree.
int size = NATIVE_ALLOCATION_SIZE;
@@ -1569,6 +1595,11 @@
}
@Override
+ public boolean hasFocusStateSpecified() {
+ return false;
+ }
+
+ @Override
int getNativeSize() {
return NATIVE_ALLOCATION_SIZE;
}
@@ -1819,6 +1850,14 @@
}
@Override
+ public boolean hasFocusStateSpecified() {
+ return (mStrokeColors != null && mStrokeColors instanceof ColorStateList &&
+ ((ColorStateList) mStrokeColors).hasFocusStateSpecified()) &&
+ (mFillColors != null && mFillColors instanceof ColorStateList &&
+ ((ColorStateList) mFillColors).hasFocusStateSpecified());
+ }
+
+ @Override
int getNativeSize() {
return NATIVE_ALLOCATION_SIZE;
}
@@ -2116,6 +2155,7 @@
abstract void applyTheme(Theme t);
abstract boolean onStateChange(int[] state);
abstract boolean isStateful();
+ abstract boolean hasFocusStateSpecified();
abstract int getNativeSize();
abstract Property getProperty(String propertyName);
}
diff --git a/graphics/java/android/graphics/fonts/FontVariationAxis.java b/graphics/java/android/graphics/fonts/FontVariationAxis.java
index 91ec0e8..fb2a3a8 100644
--- a/graphics/java/android/graphics/fonts/FontVariationAxis.java
+++ b/graphics/java/android/graphics/fonts/FontVariationAxis.java
@@ -18,8 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.text.TextUtils;
import java.util.ArrayList;
@@ -28,7 +26,7 @@
/**
* Class that holds information about single font variation axis.
*/
-public final class FontVariationAxis implements Parcelable {
+public final class FontVariationAxis {
private final int mTag;
private final String mTagString;
private final float mStyleValue;
@@ -74,39 +72,6 @@
}
/**
- * @hide
- */
- public FontVariationAxis(Parcel in) {
- mTag = in.readInt();
- mTagString = in.readString();
- mStyleValue = in.readFloat();
- }
-
- @Override
- public void writeToParcel(Parcel out, int flag) {
- out.writeInt(mTag);
- out.writeString(mTagString);
- out.writeFloat(mStyleValue);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Creator<FontVariationAxis> CREATOR = new Creator<FontVariationAxis>() {
- @Override
- public FontVariationAxis createFromParcel(Parcel in) {
- return new FontVariationAxis(in);
- }
-
- @Override
- public FontVariationAxis[] newArray(int size) {
- return new FontVariationAxis[size];
- }
- };
-
- /**
* Returns a valid font variation setting string for this object.
*/
@Override
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 9f649ea..c1cad7d 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -80,38 +80,12 @@
// Canvas state operations: Replace Bitmap
// ----------------------------------------------------------------------------
-class ClipCopier : public SkCanvas::ClipVisitor {
-public:
- explicit ClipCopier(SkCanvas* dstCanvas) : m_dstCanvas(dstCanvas) {}
-
- virtual void clipRect(const SkRect& rect, SkClipOp op, bool antialias) {
- m_dstCanvas->clipRect(rect, op, antialias);
- }
- virtual void clipRRect(const SkRRect& rrect, SkClipOp op, bool antialias) {
- m_dstCanvas->clipRRect(rrect, op, antialias);
- }
- virtual void clipPath(const SkPath& path, SkClipOp op, bool antialias) {
- m_dstCanvas->clipPath(path, op, antialias);
- }
-
-private:
- SkCanvas* m_dstCanvas;
-};
-
void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
sk_sp<SkColorSpace> cs = bitmap.refColorSpace();
std::unique_ptr<SkCanvas> newCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(bitmap));
std::unique_ptr<SkCanvas> newCanvasWrapper = SkCreateColorSpaceXformCanvas(newCanvas.get(),
cs == nullptr ? SkColorSpace::MakeSRGB() : std::move(cs));
- if (!bitmap.isNull()) {
- // Copy the canvas matrix & clip state.
- newCanvasWrapper->setMatrix(mCanvas->getTotalMatrix());
-
- ClipCopier copier(newCanvasWrapper.get());
- mCanvas->replayClips(&copier);
- }
-
// deletes the previously owned canvas (if any)
mCanvasOwned = std::move(newCanvas);
mCanvasWrapper = std::move(newCanvasWrapper);
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 7f5d3a0..bf5939f 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -2523,8 +2523,11 @@
mAvSyncHeader = ByteBuffer.allocate(16);
mAvSyncHeader.order(ByteOrder.BIG_ENDIAN);
mAvSyncHeader.putInt(0x55550001);
- mAvSyncHeader.putInt(sizeInBytes);
- mAvSyncHeader.putLong(timestamp);
+ }
+
+ if (mAvSyncBytesRemaining == 0) {
+ mAvSyncHeader.putInt(4, sizeInBytes);
+ mAvSyncHeader.putLong(8, timestamp);
mAvSyncHeader.position(0);
mAvSyncBytesRemaining = sizeInBytes;
}
@@ -2556,9 +2559,6 @@
}
mAvSyncBytesRemaining -= ret;
- if (mAvSyncBytesRemaining == 0) {
- mAvSyncHeader = null;
- }
return ret;
}
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 611fdd1..ce50cc8 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -51,12 +51,13 @@
* management messages) can be distributed out-of-band, or in-band with the stream.
* <p>
* To descramble elementary streams, the app first calls {@link #openSession} to
- * generate a sessionId that will uniquely identify a session. A session provides
- * a context for subsequent key updates and descrambling activities. The ECMs
- * (Entitlement control messages) are sent to the session via method {@link #processEcm}.
+ * generate a {@link Session} object that will uniquely identify a session. A session
+ * provides a context for subsequent key updates and descrambling activities. The ECMs
+ * (Entitlement control messages) are sent to the session via method
+ * {@link Session#processEcm}.
* <p>
* The app next constructs a MediaDescrambler object, and initializes it with the
- * sessionId using {@link MediaDescrambler#setMediaCasSession}. This ties the
+ * session using {@link MediaDescrambler#setMediaCasSession}. This ties the
* descrambler to the session, and the descrambler can then be used to descramble
* content secured with the session's key, either during extraction, or during decoding
* with {@link android.media.MediaCodec}.
@@ -79,19 +80,20 @@
* If the app uses {@link MediaExtractor}, it can delegate the CAS session
* management to MediaExtractor by calling {@link MediaExtractor#setMediaCas}.
* MediaExtractor will take over and call {@link #openSession}, {@link #processEmm}
- * and/or {@link #processEcm}, etc.. if necessary.
+ * and/or {@link Session#processEcm}, etc.. if necessary.
* <p>
* When using {@link MediaExtractor}, the app would still need a MediaDescrambler
* to use with {@link MediaCodec} if the licensing requires a secure decoder. The
- * sessionId of the descrambler can be retrieved by {@link MediaExtractor#getDrmInitData}
- * and used to initialize a MediaDescrambler object for MediaCodec.
+ * session associated with the descrambler of a track can be retrieved by calling
+ * {@link MediaExtractor#getCasInfo}, and used to initialize a MediaDescrambler
+ * object for MediaCodec.
* <p>
* <h3>Listeners</h3>
* <p>The app may register a listener to receive events from the CA system using
* method {@link #setEventListener}. The exact format of the event is scheme-specific
* and is not specified by this API.
*/
-public final class MediaCas {
+public final class MediaCas implements AutoCloseable {
private static final String TAG = "MediaCas";
private final ParcelableCasData mCasData = new ParcelableCasData();
private ICas mICas;
@@ -229,6 +231,106 @@
}
/**
+ * Class for an open session with the CA system.
+ */
+ public final class Session implements AutoCloseable {
+ final byte[] mSessionId;
+
+ Session(@NonNull byte[] sessionId) {
+ mSessionId = sessionId;
+ }
+
+ /**
+ * Set the private data for a session.
+ *
+ * @param data byte array of the private data.
+ *
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
+ */
+ public void setPrivateData(@NonNull byte[] data)
+ throws MediaCasException {
+ validateInternalStates();
+
+ try {
+ mICas.setSessionPrivateData(mSessionId, data);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
+ } catch (RemoteException e) {
+ cleanupAndRethrowIllegalState();
+ }
+ }
+
+
+ /**
+ * Send a received ECM packet to the specified session of the CA system.
+ *
+ * @param data byte array of the ECM data.
+ * @param offset position within data where the ECM data begins.
+ * @param length length of the data (starting from offset).
+ *
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
+ */
+ public void processEcm(@NonNull byte[] data, int offset, int length)
+ throws MediaCasException {
+ validateInternalStates();
+
+ try {
+ mCasData.set(data, offset, length);
+ mICas.processEcm(mSessionId, mCasData);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
+ } catch (RemoteException e) {
+ cleanupAndRethrowIllegalState();
+ }
+ }
+
+ /**
+ * Send a received ECM packet to the specified session of the CA system.
+ * This is similar to {@link Session#processEcm(byte[], int, int)}
+ * except that the entire byte array is sent.
+ *
+ * @param data byte array of the ECM data.
+ *
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
+ */
+ public void processEcm(@NonNull byte[] data) throws MediaCasException {
+ processEcm(data, 0, data.length);
+ }
+
+ /**
+ * Close the session.
+ *
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
+ */
+ @Override
+ public void close() {
+ validateInternalStates();
+
+ try {
+ mICas.closeSession(mSessionId);
+ } catch (ServiceSpecificException e) {
+ MediaCasStateException.throwExceptions(e);
+ } catch (RemoteException e) {
+ cleanupAndRethrowIllegalState();
+ }
+ }
+ }
+
+ Session createFromSessionId(byte[] sessionId) {
+ if (sessionId == null || sessionId.length == 0) {
+ return null;
+ }
+ return new Session(sessionId);
+ }
+
+ /**
* Class for parceling CAS plugin descriptors over IMediaCasService binder.
*/
static class ParcelableCasPluginDescriptor
@@ -404,21 +506,20 @@
}
/**
- * Open a session for the specified program.
+ * Open a session to descramble one or more streams scrambled by the
+ * conditional access system.
*
- * @param programNumber program_number of the program (as in ISO/IEC13818-1).
- *
- * @return session id of the newly opened session.
+ * @return session the newly opened session.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
* @throws MediaCasException for CAS-specific errors.
* @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public byte[] openSession(int programNumber) throws MediaCasException {
+ public Session openSession() throws MediaCasException {
validateInternalStates();
try {
- return mICas.openSession(programNumber);
+ return createFromSessionId(mICas.openSession());
} catch (ServiceSpecificException e) {
MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
@@ -428,118 +529,6 @@
}
/**
- * Open a session for the specified stream.
- *
- * @param programNumber program_number of the stream (as in ISO/IEC13818-1).
- * @param elementaryPID elementary_PID of the stream (as in ISO/IEC13818-1).
- *
- * @return session id of the newly opened session.
- *
- * @throws IllegalStateException if the MediaCas instance is not valid.
- * @throws MediaCasException for CAS-specific errors.
- * @throws MediaCasStateException for CAS-specific state exceptions.
- */
- public byte[] openSession(int programNumber, int elementaryPID)
- throws MediaCasException {
- validateInternalStates();
-
- try {
- return mICas.openSessionForStream(programNumber, elementaryPID);
- } catch (ServiceSpecificException e) {
- MediaCasException.throwExceptions(e);
- } catch (RemoteException e) {
- cleanupAndRethrowIllegalState();
- }
- return null;
- }
-
- /**
- * Close the specified session.
- *
- * @param sessionId the session to be closed.
- *
- * @throws IllegalStateException if the MediaCas instance is not valid.
- * @throws MediaCasStateException for CAS-specific state exceptions.
- */
- public void closeSession(@NonNull byte[] sessionId) {
- validateInternalStates();
-
- try {
- mICas.closeSession(sessionId);
- } catch (ServiceSpecificException e) {
- MediaCasStateException.throwExceptions(e);
- } catch (RemoteException e) {
- cleanupAndRethrowIllegalState();
- }
- }
-
- /**
- * Set the private data for a session.
- *
- * @param sessionId the session for which the private data is intended.
- * @param data byte array of the private data.
- *
- * @throws IllegalStateException if the MediaCas instance is not valid.
- * @throws MediaCasException for CAS-specific errors.
- * @throws MediaCasStateException for CAS-specific state exceptions.
- */
- public void setSessionPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data)
- throws MediaCasException {
- validateInternalStates();
-
- try {
- mICas.setSessionPrivateData(sessionId, data);
- } catch (ServiceSpecificException e) {
- MediaCasException.throwExceptions(e);
- } catch (RemoteException e) {
- cleanupAndRethrowIllegalState();
- }
- }
-
- /**
- * Send a received ECM packet to the specified session of the CA system.
- *
- * @param sessionId the session for which the ECM is intended.
- * @param data byte array of the ECM data.
- * @param offset position within data where the ECM data begins.
- * @param length length of the data (starting from offset).
- *
- * @throws IllegalStateException if the MediaCas instance is not valid.
- * @throws MediaCasException for CAS-specific errors.
- * @throws MediaCasStateException for CAS-specific state exceptions.
- */
- public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data,
- int offset, int length) throws MediaCasException {
- validateInternalStates();
-
- try {
- mCasData.set(data, offset, length);
- mICas.processEcm(sessionId, mCasData);
- } catch (ServiceSpecificException e) {
- MediaCasException.throwExceptions(e);
- } catch (RemoteException e) {
- cleanupAndRethrowIllegalState();
- }
- }
-
- /**
- * Send a received ECM packet to the specified session of the CA system.
- * This is similar to {@link #processEcm(byte[], byte[], int, int)}
- * except that the entire byte array is sent.
- *
- * @param sessionId the session for which the ECM is intended.
- * @param data byte array of the ECM data.
- *
- * @throws IllegalStateException if the MediaCas instance is not valid.
- * @throws MediaCasException for CAS-specific errors.
- * @throws MediaCasStateException for CAS-specific state exceptions.
- */
- public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data)
- throws MediaCasException {
- processEcm(sessionId, data, 0, data.length);
- }
-
- /**
* Send a received EMM packet to the CA system.
*
* @param data byte array of the EMM data.
@@ -650,10 +639,8 @@
}
}
- /**
- * Release the MediaCas instance.
- */
- public void release() {
+ @Override
+ public void close() {
if (mICas != null) {
try {
mICas.release();
@@ -666,6 +653,6 @@
@Override
protected void finalize() {
- release();
+ close();
}
}
\ No newline at end of file
diff --git a/media/java/android/media/MediaDescrambler.java b/media/java/android/media/MediaDescrambler.java
index 2dd1097..b75b7dd 100644
--- a/media/java/android/media/MediaDescrambler.java
+++ b/media/java/android/media/MediaDescrambler.java
@@ -38,7 +38,7 @@
* Scrambling schemes are identified by 16-bit unsigned integer as in CA_system_id.
*
*/
-public final class MediaDescrambler {
+public final class MediaDescrambler implements AutoCloseable {
private static final String TAG = "MediaDescrambler";
private IDescrambler mIDescrambler;
@@ -141,17 +141,17 @@
* android.media.MediaCodec#queueSecureInputBuffer} by specifying even
* or odd key in the {@link android.media.MediaCodec.CryptoInfo#key} field.
*
- * @param sessionId the MediaCas sessionId to associate with this
+ * @param session the MediaCas session to associate with this
* MediaDescrambler instance.
*
* @throws IllegalStateException if the descrambler instance is not valid.
* @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public final void setMediaCasSession(@NonNull byte[] sessionId) {
+ public final void setMediaCasSession(@NonNull MediaCas.Session session) {
validateInternalStates();
try {
- mIDescrambler.setMediaCasSession(sessionId);
+ mIDescrambler.setMediaCasSession(session.mSessionId);
} catch (ServiceSpecificException e) {
MediaCasStateException.throwExceptions(e);
} catch (RemoteException e) {
@@ -163,11 +163,10 @@
* Descramble a ByteBuffer of data described by a
* {@link android.media.MediaCodec.CryptoInfo} structure.
*
- * @param srcBuf ByteBuffer containing the scrambled data.
- * @param srcPos position within src where the scrambled data starts.
- * @param dstBuf ByteBuffer to descramble into. If null, descrambling will happen
- * in-place and src will be used as dst.
- * @param dstPos position within dst to put the descrambled data.
+ * @param srcBuf ByteBuffer containing the scrambled data, which starts at
+ * srcBuf.position().
+ * @param dstBuf ByteBuffer to hold the descrambled data, which starts at
+ * dstBuf.position().
* @param cryptoInfo a {@link android.media.MediaCodec.CryptoInfo} structure
* describing the subsamples contained in src.
*
@@ -178,7 +177,7 @@
* @throws MediaCasStateException for CAS-specific state exceptions.
*/
public final int descramble(
- @NonNull ByteBuffer srcBuf, int srcPos, ByteBuffer dstBuf, int dstPos,
+ @NonNull ByteBuffer srcBuf, @NonNull ByteBuffer dstBuf,
@NonNull MediaCodec.CryptoInfo cryptoInfo) {
validateInternalStates();
@@ -208,14 +207,16 @@
cryptoInfo.numSubSamples,
cryptoInfo.numBytesOfClearData,
cryptoInfo.numBytesOfEncryptedData,
- srcBuf, srcPos, dstBuf, dstPos);
+ srcBuf, srcBuf.position(), srcBuf.limit(),
+ dstBuf, dstBuf.position(), dstBuf.limit());
} catch (ServiceSpecificException e) {
MediaCasStateException.throwExceptions(e);
}
return -1;
}
- public final void release() {
+ @Override
+ public void close() {
if (mIDescrambler != null) {
try {
mIDescrambler.release();
@@ -229,7 +230,7 @@
@Override
protected void finalize() {
- release();
+ close();
}
private static native final void native_init();
@@ -237,7 +238,8 @@
private native final void native_release();
private native final int native_descramble(
byte key, int numSubSamples, int[] numBytesOfClearData, int[] numBytesOfEncryptedData,
- @NonNull ByteBuffer srcBuf, int srcOffset, ByteBuffer dstBuf, int dstOffset);
+ @NonNull ByteBuffer srcBuf, int srcOffset, int srcLimit,
+ ByteBuffer dstBuf, int dstOffset, int dstLimit);
static {
System.loadLibrary("media_jni");
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 2ed6668..a0a6a1e 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -259,11 +259,71 @@
* @param mediaCas the MediaCas object to use.
*/
public final void setMediaCas(@NonNull MediaCas mediaCas) {
+ mMediaCas = mediaCas;
nativeSetMediaCas(mediaCas.getBinder());
}
private native final void nativeSetMediaCas(@NonNull IBinder casBinder);
+ /**
+ * Describes the conditional access system used to scramble a track.
+ */
+ public static final class CasInfo {
+ private final int mSystemId;
+ private final MediaCas.Session mSession;
+
+ CasInfo(int systemId, @Nullable MediaCas.Session session) {
+ mSystemId = systemId;
+ mSession = session;
+ }
+
+ /**
+ * Retrieves the system id of the conditional access system.
+ *
+ * @return CA system id of the CAS used to scramble the track.
+ */
+ public int getSystemId() {
+ return mSystemId;
+ }
+
+ /**
+ * Retrieves the {@link MediaCas.Session} associated with a track. The
+ * session is needed to initialize a descrambler in order to decode the
+ * scrambled track.
+ * <p>
+ * @see MediaDescrambler#setMediaCasSession
+ * <p>
+ * @return a {@link MediaCas.Session} object associated with a track.
+ */
+ public MediaCas.Session getSession() {
+ return mSession;
+ }
+ }
+
+ /**
+ * Retrieves the information about the conditional access system used to scramble
+ * a track.
+ *
+ * @param index of the track.
+ * @return an {@link CasInfo} object describing the conditional access system.
+ */
+ public CasInfo getCasInfo(int index) {
+ Map<String, Object> formatMap = getTrackFormatNative(index);
+ if (formatMap.containsKey(MediaFormat.KEY_CA_SYSTEM_ID)) {
+ int systemId = ((Integer)formatMap.get(MediaFormat.KEY_CA_SYSTEM_ID)).intValue();
+ MediaCas.Session session = null;
+ if (mMediaCas != null && formatMap.containsKey(MediaFormat.KEY_CA_SESSION_ID)) {
+ ByteBuffer buf = (ByteBuffer) formatMap.get(MediaFormat.KEY_CA_SESSION_ID);
+ buf.rewind();
+ final byte[] sessionId = new byte[buf.remaining()];
+ buf.get(sessionId);
+ session = mMediaCas.createFromSessionId(sessionId);
+ }
+ return new CasInfo(systemId, session);
+ }
+ return null;
+ }
+
@Override
protected void finalize() {
native_finalize();
@@ -307,31 +367,6 @@
return initDataMap.get(schemeUuid);
}
};
- } else if (formatMap.containsKey("mime")
- && "video/mp2ts".equals(formatMap.get("mime"))) {
- final Map<UUID, DrmInitData.SchemeInitData> initDataMap =
- new HashMap<UUID, DrmInitData.SchemeInitData>();
-
- int numTracks = getTrackCount();
- for (int i = 0; i < numTracks; ++i) {
- Map<String, Object> trackFormatMap = getTrackFormatNative(i);
- if (!trackFormatMap.containsKey("cas")) {
- continue;
- }
- ByteBuffer buf = (ByteBuffer) trackFormatMap.get("cas");
- buf.rewind();
- final byte[] data = new byte[buf.remaining()];
- buf.get(data);
- initDataMap.put(new UUID(0, i), new DrmInitData.SchemeInitData("cas", data));
- }
- if (initDataMap.isEmpty()) {
- return null;
- }
- return new DrmInitData() {
- public SchemeInitData get(UUID schemeUuid) {
- return initDataMap.get(schemeUuid);
- }
- };
} else {
int numTracks = getTrackCount();
for (int i = 0; i < numTracks; ++i) {
@@ -349,8 +384,8 @@
}
};
}
- return null;
}
+ return null;
}
/**
@@ -680,5 +715,7 @@
native_init();
}
+ private MediaCas mMediaCas;
+
private long mNativeContext;
}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index e77c00b..ed5f7d8 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -767,6 +767,29 @@
*/
public static final String KEY_TRACK_ID = "track-id";
+ /**
+ * A key describing the system id of the conditional access system used to scramble
+ * a media track.
+ * <p>
+ * This key is set by {@link MediaExtractor} if the track is scrambled with a conditional
+ * access system.
+ * <p>
+ * The associated value is an integer.
+ * @hide
+ */
+ public static final String KEY_CA_SYSTEM_ID = "ca-system-id";
+
+ /**
+ * A key describing the {@link MediaCas.Session} object associated with a media track.
+ * <p>
+ * This key is set by {@link MediaExtractor} if the track is scrambled with a conditional
+ * access system.
+ * <p>
+ * The associated value is a ByteBuffer.
+ * @hide
+ */
+ public static final String KEY_CA_SESSION_ID = "ca-session-id";
+
/* package private */ MediaFormat(Map<String, Object> map) {
mMap = map;
}
diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java
index af11e07..1dda6a4 100644
--- a/media/java/android/media/VolumeShaper.java
+++ b/media/java/android/media/VolumeShaper.java
@@ -301,7 +301,7 @@
.setInterpolatorType(INTERPOLATOR_TYPE_LINEAR)
.setCurve(new float[] {0.f, 1.f} /* times */,
new float[] {0.f, 1.f} /* volumes */)
- .setDurationMs(1000.)
+ .setDurationMillis(1000.)
.build();
/**
@@ -314,7 +314,7 @@
.setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
.setCurve(new float[] {0.f, 1.f} /* times */,
new float[] {0.f, 1.f} /* volumes */)
- .setDurationMs(1000.)
+ .setDurationMillis(1000.)
.build();
/**
@@ -348,12 +348,12 @@
SINE_RAMP = new VolumeShaper.Configuration.Builder()
.setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
.setCurve(times, sines)
- .setDurationMs(1000.)
+ .setDurationMillis(1000.)
.build();
SCURVE_RAMP = new VolumeShaper.Configuration.Builder()
.setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
.setCurve(times, scurve)
- .setDurationMs(1000.)
+ .setDurationMillis(1000.)
.build();
}
@@ -569,7 +569,7 @@
/**
* Returns the duration of the volume shape in milliseconds.
*/
- public double getDurationMs() {
+ public double getDurationMillis() {
return mDurationMs;
}
@@ -700,7 +700,7 @@
* .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
* .setCurve(new float[] { 0.f, 1.f }, // times
* new float[] { 0.f, 1.f }) // volumes
- * .setDurationMs(1000.)
+ * .setDurationMillis(1000.)
* .build();
* </pre>
* <p>
@@ -731,7 +731,7 @@
mId = configuration.getId();
mOptionFlags = configuration.getAllOptionFlags();
mInterpolatorType = configuration.getInterpolatorType();
- mDurationMs = configuration.getDurationMs();
+ mDurationMs = configuration.getDurationMillis();
mTimes = configuration.getTimes().clone();
mVolumes = configuration.getVolumes().clone();
}
@@ -805,17 +805,17 @@
*
* If omitted, the default duration is 1 second.
*
- * @param durationMs
+ * @param durationMillis
* @return the same {@code Builder} instance.
- * @throws IllegalArgumentException if {@code durationMs}
+ * @throws IllegalArgumentException if {@code durationMillis}
* is not strictly positive.
*/
- public @NonNull Builder setDurationMs(double durationMs) {
- if (durationMs <= 0.) {
+ public @NonNull Builder setDurationMillis(double durationMillis) {
+ if (durationMillis <= 0.) {
throw new IllegalArgumentException(
- "duration: " + durationMs + " not positive");
+ "duration: " + durationMillis + " not positive");
}
- mDurationMs = durationMs;
+ mDurationMs = durationMillis;
return this;
}
@@ -833,7 +833,7 @@
* time (x) coordinates should be monotonically increasing, from 0.f to 1.f;
* volume (y) coordinates must be within 0.f to 1.f.
* <p>
- * The time scale is set by {@link #setDurationMs}.
+ * The time scale is set by {@link #setDurationMillis}.
* <p>
* @param times an array of float values representing
* the time line of the volume curve.
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index e82dd82..6635b5f 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -589,6 +589,36 @@
* @hide
*/
interface ProgramColumns {
+ /** @hide */
+ @IntDef({
+ REVIEW_RATING_STYLE_STARS,
+ REVIEW_RATING_STYLE_THUMBS_UP_DOWN,
+ REVIEW_RATING_STYLE_PERCENTAGE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ReviewRatingStyle {}
+
+ /**
+ * The review rating style for five star rating.
+ *
+ * @see #COLUMN_REVIEW_RATING_STYLE
+ */
+ int REVIEW_RATING_STYLE_STARS = 0;
+
+ /**
+ * The review rating style for thumbs-up and thumbs-down rating.
+ *
+ * @see #COLUMN_REVIEW_RATING_STYLE
+ */
+ int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1;
+
+ /**
+ * The review rating style for 0 to 100 point system.
+ *
+ * @see #COLUMN_REVIEW_RATING_STYLE
+ */
+ int REVIEW_RATING_STYLE_PERCENTAGE = 2;
+
/**
* The title of this TV program.
*
@@ -851,6 +881,33 @@
* <p>Type: INTEGER
*/
String COLUMN_VERSION_NUMBER = "version_number";
+
+ /**
+ * The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
+ *
+ * <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS},
+ * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
+ *
+ * <p>Type: INTEGER
+ * @see #COLUMN_REVIEW_RATING
+ */
+ String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+
+ /**
+ * The review rating score for this program.
+ *
+ * <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the
+ * style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between
+ * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN},
+ * the value should be two integers, one for thumbs-up count and the other for thumbs-down
+ * count, with a comma between them. (e.g. "200,40") If the style is
+ * {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and
+ * 100. (e.g. "99.9")
+ *
+ * <p>Type: TEXT
+ * @see #COLUMN_REVIEW_RATING_STYLE
+ */
+ String COLUMN_REVIEW_RATING = "review_rating";
}
/**
@@ -1096,36 +1153,6 @@
*/
int INTERACTION_TYPE_VIEWERS = 6;
- /** @hide */
- @IntDef({
- REVIEW_RATING_STYLE_STARS,
- REVIEW_RATING_STYLE_THUMBS_UP_DOWN,
- REVIEW_RATING_STYLE_PERCENTAGE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ReviewRatingStyle {}
-
- /**
- * The review rating style for five star rating.
- *
- * @see #COLUMN_REVIEW_RATING_STYLE
- */
- int REVIEW_RATING_STYLE_STARS = 0;
-
- /**
- * The review rating style for thumbs-up and thumbs-down rating.
- *
- * @see #COLUMN_REVIEW_RATING_STYLE
- */
- int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1;
-
- /**
- * The review rating style for 0 to 100 point system.
- *
- * @see #COLUMN_REVIEW_RATING_STYLE
- */
- int REVIEW_RATING_STYLE_PERCENTAGE = 2;
-
/**
* The type of this program content.
*
@@ -1375,33 +1402,6 @@
String COLUMN_AUTHOR = "author";
/**
- * The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
- *
- * <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS},
- * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
- *
- * <p>Type: INTEGER
- * @see #COLUMN_REVIEW_RATING
- */
- String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
-
- /**
- * The review rating score for this program.
- *
- * <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the
- * style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between
- * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN},
- * the value should be two integers, one for thumbs-up count and the other for thumbs-down
- * count, with a comma between them. (e.g. "200,40") If the style is
- * {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and
- * 100. (e.g. "99.9")
- *
- * <p>Type: TEXT
- * @see #COLUMN_REVIEW_RATING_STYLE
- */
- String COLUMN_REVIEW_RATING = "review_rating";
-
- /**
* The flag indicating whether this TV program is browsable or not.
*
* <p>This column can only be set by applications having proper system permission. For
diff --git a/media/jni/android_media_MediaDescrambler.cpp b/media/jni/android_media_MediaDescrambler.cpp
index f031dbb..85d33b7 100644
--- a/media/jni/android_media_MediaDescrambler.cpp
+++ b/media/jni/android_media_MediaDescrambler.cpp
@@ -54,11 +54,10 @@
}
static status_t getBufferAndSize(
- JNIEnv *env, jobject byteBuf, jint offset, size_t length,
+ JNIEnv *env, jobject byteBuf, jint offset, jint limit, size_t length,
void **outPtr, jbyteArray *outByteArray) {
void *ptr = env->GetDirectBufferAddress(byteBuf);
- size_t bufSize;
jbyteArray byteArray = NULL;
ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer"));
@@ -78,13 +77,9 @@
jboolean isCopy;
ptr = env->GetByteArrayElements(byteArray, &isCopy);
-
- bufSize = (size_t) env->GetArrayLength(byteArray);
- } else {
- bufSize = (size_t) env->GetDirectBufferCapacity(byteBuf);
}
- if (length + offset > bufSize) {
+ if ((jint)length + offset > limit) {
if (byteArray != NULL) {
env->ReleaseByteArrayElements(byteArray, (jbyte *)ptr, 0);
}
@@ -294,7 +289,8 @@
static jint android_media_MediaDescrambler_native_descramble(
JNIEnv *env, jobject thiz, jbyte key, jint numSubSamples,
jintArray numBytesOfClearDataObj, jintArray numBytesOfEncryptedDataObj,
- jobject srcBuf, jint srcOffset, jobject dstBuf, jint dstOffset) {
+ jobject srcBuf, jint srcOffset, jint srcLimit,
+ jobject dstBuf, jint dstOffset, jint dstLimit) {
sp<JDescrambler> descrambler = getDescrambler(env, thiz);
if (descrambler == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
@@ -307,7 +303,7 @@
numBytesOfEncryptedDataObj, &subSamples);
if (totalLength < 0) {
jniThrowException(env, "java/lang/IllegalArgumentException",
- "Invalid sub sample info!");
+ "Invalid subsample info!");
return -1;
}
@@ -315,16 +311,23 @@
void *srcPtr = NULL, *dstPtr = NULL;
jbyteArray srcArray = NULL, dstArray = NULL;
status_t err = getBufferAndSize(
- env, srcBuf, srcOffset, totalLength, &srcPtr, &srcArray);
+ env, srcBuf, srcOffset, srcLimit, totalLength, &srcPtr, &srcArray);
if (err == OK) {
if (dstBuf == NULL) {
dstPtr = srcPtr;
} else {
err = getBufferAndSize(
- env, dstBuf, dstOffset, totalLength, &dstPtr, &dstArray);
+ env, dstBuf, dstOffset, dstLimit, totalLength, &dstPtr, &dstArray);
}
}
+
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "Invalid buffer offset and/or size for subsamples!");
+ return -1;
+ }
+
Status status;
if (err == OK) {
status = descrambler->descramble(
@@ -394,7 +397,7 @@
(void *)android_media_MediaDescrambler_native_init },
{ "native_setup", "(Landroid/os/IBinder;)V",
(void *)android_media_MediaDescrambler_native_setup },
- { "native_descramble", "(BI[I[ILjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)I",
+ { "native_descramble", "(BI[I[ILjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;II)I",
(void *)android_media_MediaDescrambler_native_descramble },
};
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index e60b5a9..db88f2c 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -509,7 +509,7 @@
final DeviceToolkit toolkit =
new DeviceToolkit(mMtpManager, mResolver, mDatabase, device);
mDeviceToolkits.put(deviceId, toolkit);
- mIntentSender.sendUpdateNotificationIntent(device);
+ mIntentSender.sendUpdateNotificationIntent(getOpenedDeviceRecordsCache());
try {
mRootScanner.resume().await();
} catch (InterruptedException error) {
@@ -524,9 +524,9 @@
void closeDevice(int deviceId) throws IOException, InterruptedException {
synchronized (mDeviceListLock) {
closeDeviceInternal(deviceId);
+ mIntentSender.sendUpdateNotificationIntent(getOpenedDeviceRecordsCache());
}
mRootScanner.resume();
- mIntentSender.sendUpdateNotificationIntent(null);
}
MtpDeviceRecord[] getOpenedDeviceRecordsCache() {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
index 664d3c9..fa1a12030 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
@@ -16,13 +16,17 @@
package com.android.mtp;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.Notification;
import android.app.Service;
import android.app.NotificationManager;
-import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
+import android.os.Parcelable;
import android.service.notification.StatusBarNotification;
+import android.util.Log;
+import com.android.internal.util.Preconditions;
import java.util.HashSet;
import java.util.Set;
@@ -33,7 +37,8 @@
*/
public class MtpDocumentsService extends Service {
static final String ACTION_UPDATE_NOTIFICATION = "com.android.mtp.UPDATE_NOTIFICATION";
- static final String EXTRA_DEVICE = "device";
+ static final String EXTRA_DEVICE_IDS = "deviceIds";
+ static final String EXTRA_DEVICE_NOTIFICATIONS = "deviceNotifications";
private NotificationManager mNotificationManager;
@@ -53,7 +58,12 @@
public int onStartCommand(Intent intent, int flags, int startId) {
// If intent is null, the service was restarted.
if (intent == null || ACTION_UPDATE_NOTIFICATION.equals(intent.getAction())) {
- return updateForegroundState() ? START_STICKY : START_NOT_STICKY;
+ final int[] ids = intent.hasExtra(EXTRA_DEVICE_IDS) ?
+ intent.getExtras().getIntArray(EXTRA_DEVICE_IDS) : null;
+ final Notification[] notifications = intent.hasExtra(EXTRA_DEVICE_NOTIFICATIONS) ?
+ castToNotifications(intent.getExtras().getParcelableArray(
+ EXTRA_DEVICE_NOTIFICATIONS)) : null;
+ return updateForegroundState(ids, notifications) ? START_STICKY : START_NOT_STICKY;
}
return START_NOT_STICKY;
}
@@ -62,35 +72,38 @@
* Updates the foreground state of the service.
* @return Whether the service is foreground or not.
*/
- private boolean updateForegroundState() {
- final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
+ private boolean updateForegroundState(
+ @Nullable int[] ids, @Nullable Notification[] notifications) {
final Set<Integer> openedNotification = new HashSet<>();
- boolean hasForegroundNotification = false;
+ final int size = ids != null ? ids.length : 0;
+ if (size != 0) {
+ Preconditions.checkArgument(ids != null);
+ Preconditions.checkArgument(notifications != null);
+ Preconditions.checkArgument(ids.length == notifications.length);
+ }
+
+ for (int i = 0; i < size; i++) {
+ if (i == 0) {
+ // Mark this service as foreground with the notification so that the process is
+ // not killed by the system while a MTP device is opened.
+ startForeground(ids[i], notifications[i]);
+ } else {
+ // Only one notification can be shown as a foreground notification. We need to
+ // show the rest as normal notification.
+ mNotificationManager.notify(ids[i], notifications[i]);
+ }
+ openedNotification.add(ids[i]);
+ }
final StatusBarNotification[] activeNotifications =
mNotificationManager.getActiveNotifications();
-
- for (final MtpDeviceRecord record : provider.getOpenedDeviceRecordsCache()) {
- openedNotification.add(record.deviceId);
- if (!hasForegroundNotification) {
- // Mark this service as foreground with the notification so that the process is not
- // killed by the system while a MTP device is opened.
- startForeground(record.deviceId, createNotification(this, record));
- hasForegroundNotification = true;
- } else {
- // Only one notification can be shown as a foreground notification. We need to show
- // the rest as normal notification.
- mNotificationManager.notify(record.deviceId, createNotification(this, record));
- }
- }
-
for (final StatusBarNotification notification : activeNotifications) {
if (!openedNotification.contains(notification.getId())) {
mNotificationManager.cancel(notification.getId());
}
}
- if (!hasForegroundNotification) {
+ if (size == 0) {
// There is no opened device.
stopForeground(true /* removeNotification */);
stopSelf();
@@ -100,17 +113,12 @@
return true;
}
- public static Notification createNotification(Context context, MtpDeviceRecord device) {
- final String title = context.getResources().getString(
- R.string.accessing_notification_title,
- device.name);
- return new Notification.Builder(context)
- .setLocalOnly(true)
- .setContentTitle(title)
- .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
- .setCategory(Notification.CATEGORY_SYSTEM)
- .setPriority(Notification.PRIORITY_LOW)
- .setFlag(Notification.FLAG_NO_CLEAR, true)
- .build();
+ private static @NonNull Notification[] castToNotifications(@NonNull Parcelable[] src) {
+ Preconditions.checkNotNull(src);
+ final Notification[] notifications = new Notification[src.length];
+ for (int i = 0; i < src.length; i++) {
+ notifications[i] = (Notification) src[i];
+ }
+ return notifications;
}
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java b/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
index d8c3d35..c5292b8 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
@@ -16,11 +16,12 @@
package com.android.mtp;
-import android.annotation.Nullable;
-import android.app.NotificationManager;
+import android.annotation.NonNull;
+import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import com.android.internal.util.Preconditions;
/**
* Sends intent to MtpDocumentsService.
@@ -34,20 +35,38 @@
/**
* Notify the change of opened device set.
- * @param record If a new device is opened, pass the device record. If a device is closed, pass
- * null.
+ * @param records List of opened devices. Can be empty.
*/
- void sendUpdateNotificationIntent(@Nullable MtpDeviceRecord record) {
+ void sendUpdateNotificationIntent(@NonNull MtpDeviceRecord[] records) {
+ Preconditions.checkNotNull(records);
final Intent intent = new Intent(MtpDocumentsService.ACTION_UPDATE_NOTIFICATION);
intent.setComponent(new ComponentName(mContext, MtpDocumentsService.class));
- final NotificationManager manager = mContext.getSystemService(NotificationManager.class);
- if (record != null) {
- manager.startServiceInForeground(
- intent,
- record.deviceId,
- MtpDocumentsService.createNotification(mContext, record));
+ if (records.length != 0) {
+ final int[] ids = new int[records.length];
+ final Notification[] notifications = new Notification[records.length];
+ for (int i = 0; i < records.length; i++) {
+ ids[i] = records[i].deviceId;
+ notifications[i] = createNotification(mContext, records[i]);
+ }
+ intent.putExtra(MtpDocumentsService.EXTRA_DEVICE_IDS, ids);
+ intent.putExtra(MtpDocumentsService.EXTRA_DEVICE_NOTIFICATIONS, notifications);
+ mContext.startForegroundService(intent);
} else {
mContext.startService(intent);
}
}
+
+ private static Notification createNotification(Context context, MtpDeviceRecord device) {
+ final String title = context.getResources().getString(
+ R.string.accessing_notification_title,
+ device.name);
+ return new Notification.Builder(context)
+ .setLocalOnly(true)
+ .setContentTitle(title)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setPriority(Notification.PRIORITY_LOW)
+ .setFlag(Notification.FLAG_NO_CLEAR, true)
+ .build();
+ }
}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
index 74dd429..ed2dc38 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
@@ -16,13 +16,11 @@
package com.android.mtp;
-import android.annotation.Nullable;
-
class TestServiceIntentSender extends ServiceIntentSender {
TestServiceIntentSender() {
super(null);
}
@Override
- void sendUpdateNotificationIntent(@Nullable MtpDeviceRecord record) {}
+ void sendUpdateNotificationIntent(MtpDeviceRecord[] record) {}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 78ad34a..0ab296e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -186,6 +186,11 @@
TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
float alpha = ta.getFloat(0, 0);
ta.recycle();
+ return applyAlpha(alpha, inputColor);
+ }
+
+ @ColorInt
+ public static int applyAlpha(float alpha, int inputColor) {
alpha *= Color.alpha(inputColor);
return Color.argb((int) (alpha), Color.red(inputColor), Color.green(inputColor),
Color.blue(inputColor));
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
index 85b04c8..820231e 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
@@ -159,14 +159,14 @@
for (String pkg : defaultImes) {
final ResolveInfo ri = createResolveInfoForSystemApp(pkg);
final InputMethodInfo inputMethodInfo = new InputMethodInfo(
- ri, false, null, null, 0, true, true, false);
+ ri, false, null, null, 0, true, true);
inputMethods.add(inputMethodInfo);
addInstalledApp(ri);
}
for (String pkg : otherImes) {
final ResolveInfo ri = createResolveInfoForSystemApp(pkg);
final InputMethodInfo inputMethodInfo = new InputMethodInfo(
- ri, false, null, null, 0, false, true, false);
+ ri, false, null, null, 0, false, true);
inputMethods.add(inputMethodInfo);
addInstalledApp(ri);
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 4a54c0e..bac694f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1435,8 +1435,8 @@
Settings.Secure.DEMO_USER_SETUP_COMPLETE,
SecureSettingsProto.DEMO_USER_SETUP_COMPLETE);
dumpSetting(s, p,
- Settings.Secure.WEB_ACTION_ENABLED,
- SecureSettingsProto.WEB_ACTION_ENABLED);
+ Settings.Secure.INSTANT_APPS_ENABLED,
+ SecureSettingsProto.INSTANT_APPS_ENABLED);
dumpSetting(s, p,
Settings.Secure.DEVICE_PAIRED,
SecureSettingsProto.DEVICE_PAIRED);
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index 5809bfc..805aed6 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -23,7 +23,9 @@
<string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaju se detalji u izveštaj o grešci"</string>
<string name="bugreport_updating_wait" msgid="3322151947853929470">"Sačekajte..."</string>
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izveštaj o grešci će se uskoro pojaviti na telefonu"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Izaberite da biste delili izveštaj o grešci"</string>
<string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste delili izveštaj o grešci"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Izaberite da biste delili izveštaj o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
<string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"Izveštaji o greškama sadrže podatke iz različitih sistemskih datoteka evidencije, koji obuhvataju lične i privatne podatke (poput korišćenja aplikacija i podataka o lokaciji). Delite izveštaje o greškama samo sa aplikacijama i ljudima u koje imate poverenja."</string>
diff --git a/packages/Shell/res/values-be/strings.xml b/packages/Shell/res/values-be/strings.xml
index f69317c..bea1c30 100644
--- a/packages/Shell/res/values-be/strings.xml
+++ b/packages/Shell/res/values-be/strings.xml
@@ -23,7 +23,9 @@
<string name="bugreport_updating_title" msgid="4423539949559634214">"Дадаванне падрабязнасцей да справаздачы пра памылкі"</string>
<string name="bugreport_updating_wait" msgid="3322151947853929470">"Калі ласка, пачакайце..."</string>
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Паведамленне пра памылку хутка з\'явіцца на тэлефоне"</string>
+ <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_confirm" msgid="5917407234515812495">"Справаздачы пра памылкі ўтрымліваюць даныя з розных файлаў журналаў сістэмы, якія могуць уключаць даныя, што вы лічыце канфідэнцыяльнымі (напрыклад, пра выкарыстанне праграм і даныя аб месцазнаходжанні). Абагульвайце справаздачы пра памылкі толькі з тымі людзьмі і праграмамі, якім вы давяраеце."</string>
diff --git a/packages/Shell/res/values-bs/strings.xml b/packages/Shell/res/values-bs/strings.xml
index 8815e94..fab8063 100644
--- a/packages/Shell/res/values-bs/strings.xml
+++ b/packages/Shell/res/values-bs/strings.xml
@@ -23,7 +23,9 @@
<string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje detalja u izvještaj o greškama"</string>
<string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string>
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izvještaj o greškama će se ubrzo pojaviti na ekranu"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Odaberite da podijelite izvještaj o greškama"</string>
<string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvještaj o grešci"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Odaberite da podijelite izvještaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
<string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema koji mogu sadržavati lične i privatne informacije koje smatrate osjetljivima (poput podataka o upotrebi aplikacije ili podataka o lokaciji). Izvještaje o greškama dijelite samo sa aplikacijama i osobama kojima vjerujete."</string>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
index 8dde357..4a7d0fd 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
@@ -37,7 +37,7 @@
public interface NotificationMenuRowPlugin extends Plugin {
public static final String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_MENU_ROW";
- public static final int VERSION = 1;
+ public static final int VERSION = 2;
@ProvidesInterface(version = OnMenuEventListener.VERSION)
public interface OnMenuEventListener {
@@ -89,6 +89,8 @@
public void onHeightUpdate();
+ public void onNotificationUpdated();
+
public boolean onTouchEvent(View view, MotionEvent ev, float velocity);
public default boolean useDefaultMenuItems() {
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 8ea9e06..0bdbc5f 100644
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -15,6 +15,6 @@
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<shape>
- <solid android:color="?android:attr/colorPrimary"/>
+ <solid android:color="?android:attr/colorPrimaryDark"/>
</shape>
</inset>
diff --git a/packages/SystemUI/res/drawable/qs_dual_tile_caret.xml b/packages/SystemUI/res/drawable/qs_dual_tile_caret.xml
index 0b2bd22..e27bc7a 100644
--- a/packages/SystemUI/res/drawable/qs_dual_tile_caret.xml
+++ b/packages/SystemUI/res/drawable/qs_dual_tile_caret.xml
@@ -14,8 +14,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
+ android:width="18.0dp"
+ android:height="18.0dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml
index 44ced17..8c66bab 100644
--- a/packages/SystemUI/res/layout/pip_menu_activity.xml
+++ b/packages/SystemUI/res/layout/pip_menu_activity.xml
@@ -26,16 +26,6 @@
android:layout_height="match_parent"
android:forceHasOverlappingRendering="false">
- <ImageView
- android:id="@+id/dismiss"
- android:layout_width="@dimen/pip_action_size"
- android:layout_height="@dimen/pip_action_size"
- android:layout_gravity="top|end"
- android:padding="@dimen/pip_action_padding"
- android:contentDescription="@string/pip_phone_close"
- android:src="@drawable/ic_close_white"
- android:background="?android:selectableItemBackgroundBorderless" />
-
<!-- The margins for this container is calculated in the code depending on whether the
actions_container is visible. -->
<FrameLayout
@@ -67,4 +57,15 @@
android:showDividers="middle" />
</FrameLayout>
</FrameLayout>
+
+ <ImageView
+ android:id="@+id/dismiss"
+ android:layout_width="@dimen/pip_action_size"
+ android:layout_height="@dimen/pip_action_size"
+ android:layout_gravity="top|end"
+ android:padding="@dimen/pip_action_padding"
+ android:contentDescription="@string/pip_phone_close"
+ android:src="@drawable/ic_close_white"
+ android:background="?android:selectableItemBackgroundBorderless" />
+
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/qs_divider.xml b/packages/SystemUI/res/layout/qs_divider.xml
index 660e4af..39d48ea 100644
--- a/packages/SystemUI/res/layout/qs_divider.xml
+++ b/packages/SystemUI/res/layout/qs_divider.xml
@@ -16,6 +16,5 @@
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="1dp"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
+ android:alpha=".12"
android:background="?android:attr/colorForeground" />
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 64caefd..9b53a97 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -21,7 +21,7 @@
android:clipChildren="false"
android:clipToPadding="false"
android:minHeight="48dp"
- android:paddingTop="8dp">
+ android:paddingTop="12dp">
<LinearLayout
android:id="@+id/label_group"
android:layout_width="wrap_content"
@@ -31,6 +31,10 @@
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="horizontal">
+ <Space
+ android:id="@+id/expand_space"
+ android:layout_width="22dp"
+ android:layout_height="0dp" />
<TextView
android:id="@+id/tile_label"
@@ -44,14 +48,6 @@
android:textAppearance="@style/TextAppearance.QS.TileLabel"
android:textColor="?android:attr/textColorPrimary"/>
- <ImageView
- android:id="@+id/expand_indicator"
- android:layout_marginStart="4dp"
- android:layout_width="12dp"
- android:layout_height="match_parent"
- android:src="@drawable/qs_dual_tile_caret"
- android:tint="?android:attr/textColorPrimary" />
-
<ImageView android:id="@+id/restricted_padlock"
android:layout_width="@dimen/qs_tile_text_size"
android:layout_height="match_parent"
@@ -60,6 +56,14 @@
android:layout_marginLeft="@dimen/restricted_padlock_pading"
android:scaleType="centerInside"
android:visibility="gone" />
+
+ <ImageView
+ android:id="@+id/expand_indicator"
+ android:layout_marginStart="4dp"
+ android:layout_width="18dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/qs_dual_tile_caret"
+ android:tint="?android:attr/textColorPrimary" />
</LinearLayout>
<TextView
@@ -85,6 +89,7 @@
android:layout_alignStart="@id/label_group"
android:layout_alignEnd="@id/label_group"
android:layout_below="@id/label_group"
+ android:visibility="gone"
android:alpha="?android:attr/disabledAlpha"
android:background="?android:attr/colorForeground"/>
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index c0be676..8707840 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -18,104 +18,155 @@
<com.android.systemui.volume.ZenModePanel xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/zen_mode_panel"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:orientation="vertical" >
-
- <com.android.systemui.volume.SegmentedButtons
- android:id="@+id/zen_buttons"
- android:background="@drawable/segmented_buttons_background"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp" />
-
- <RelativeLayout
- android:id="@+id/zen_introduction"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:background="@drawable/zen_introduction_message_background"
- android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent.Light">
-
- <ImageView
- android:id="@+id/zen_introduction_confirm"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:layout_marginEnd="8dp"
- android:layout_alignParentEnd="true"
- android:background="@drawable/btn_borderless_rect"
- android:clickable="true"
- android:contentDescription="@string/accessibility_desc_close"
- android:scaleType="center"
- android:src="@drawable/ic_close"
- android:tint="@android:color/white" />
-
- <TextView
- android:id="@+id/zen_introduction_message"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
- android:layout_marginStart="24dp"
- android:textDirection="locale"
- android:lineSpacingMultiplier="1.20029"
- android:layout_toStartOf="@id/zen_introduction_confirm"
- android:textAppearance="@style/TextAppearance.QS.Introduction" />
-
- <TextView
- android:id="@+id/zen_introduction_customize"
- style="@style/QSBorderlessButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_marginEnd="12dp"
- android:layout_below="@id/zen_introduction_message"
- android:clickable="true"
- android:focusable="true"
- android:text="@string/zen_priority_customize_button"
- android:textAppearance="@style/TextAppearance.QS.DetailButton.White" />
-
- <View
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_below="@id/zen_introduction_message"
- android:layout_alignParentEnd="true" />
-
- </RelativeLayout>
+ android:layout_height="match_parent"
+ android:clipChildren="false" >
<LinearLayout
- android:id="@+id/zen_conditions"
+ android:id="@+id/edit_container"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginEnd="4dp"
- android:layout_marginStart="4dp"
- android:paddingBottom="@dimen/zen_mode_condition_detail_bottom_padding"
- android:orientation="horizontal" >
+ android:layout_height="match_parent"
+ android:background="?android:attr/colorPrimary"
+ android:clipChildren="false"
+ android:orientation="vertical">
+
+ <com.android.systemui.volume.SegmentedButtons
+ android:id="@+id/zen_buttons"
+ android:background="@drawable/segmented_buttons_background"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp" />
+
+ <RelativeLayout
+ android:id="@+id/zen_introduction"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:background="@drawable/zen_introduction_message_background"
+ android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent.Light">
+
+ <ImageView
+ android:id="@+id/zen_introduction_confirm"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_marginEnd="8dp"
+ android:layout_alignParentEnd="true"
+ android:background="@drawable/btn_borderless_rect"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_desc_close"
+ android:scaleType="center"
+ android:src="@drawable/ic_close"
+ android:tint="@android:color/white" />
+
+ <TextView
+ android:id="@+id/zen_introduction_message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="12dp"
+ android:layout_marginStart="24dp"
+ android:textDirection="locale"
+ android:lineSpacingMultiplier="1.20029"
+ android:layout_toStartOf="@id/zen_introduction_confirm"
+ android:textAppearance="@style/TextAppearance.QS.Introduction" />
+
+ <TextView
+ android:id="@+id/zen_introduction_customize"
+ style="@style/QSBorderlessButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_marginEnd="12dp"
+ android:layout_below="@id/zen_introduction_message"
+ android:clickable="true"
+ android:focusable="true"
+ android:text="@string/zen_priority_customize_button"
+ android:textAppearance="@style/TextAppearance.QS.DetailButton.White" />
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="16dp"
+ android:layout_below="@id/zen_introduction_message"
+ android:layout_alignParentEnd="true" />
+
+ </RelativeLayout>
+
+ <LinearLayout
+ android:id="@+id/zen_conditions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="4dp"
+ android:layout_marginStart="4dp"
+ android:paddingBottom="@dimen/zen_mode_condition_detail_bottom_padding"
+ android:orientation="horizontal" >
<RadioGroup
- android:id="@+id/zen_radio_buttons"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ android:id="@+id/zen_radio_buttons"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
<LinearLayout
- android:id="@+id/zen_radio_buttons_content"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical"/>
+ android:id="@+id/zen_radio_buttons_content"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/zen_alarm_warning"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="18dp"
+ android:layout_marginEnd="16dp"
+ android:textDirection="locale"
+ android:lineSpacingMultiplier="1.20029"
+ android:textAppearance="@style/TextAppearance.QS.Warning" />
</LinearLayout>
- <TextView
- android:id="@+id/zen_alarm_warning"
+ <LinearLayout
+ android:id="@android:id/empty"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="18dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:background="?android:attr/colorPrimary"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:alpha="?android:attr/disabledAlpha"
+ android:tint="?android:attr/colorForeground" />
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="20dp"
+ android:textAppearance="@style/TextAppearance.QS.DetailEmpty"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/auto_rule"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?android:attr/colorPrimary"
+ android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
- android:textDirection="locale"
- android:lineSpacingMultiplier="1.20029"
- android:textAppearance="@style/TextAppearance.QS.Warning" />
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="8dp"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"/>
+
+ </LinearLayout>
</com.android.systemui.volume.ZenModePanel>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 809648a..6837340 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -218,8 +218,8 @@
<!-- The size of the gesture span needed to activate the "pull" notification expansion -->
<dimen name="pull_span_min">25dp</dimen>
- <dimen name="qs_tile_height">88dp</dimen>
- <dimen name="qs_tile_margin">28dp</dimen>
+ <dimen name="qs_tile_height">106dp</dimen>
+ <dimen name="qs_tile_margin">19dp</dimen>
<dimen name="qs_tile_margin_top">16dp</dimen>
<dimen name="qs_quick_tile_size">48dp</dimen>
<dimen name="qs_quick_tile_padding">12dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7bd9526..eeb28c8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1895,6 +1895,13 @@
<!-- Tuner string -->
<string name="default_theme" translatable="false">Default</string>
+ <!-- Title for notification & dialog that the user's phone last shut down because it got too hot. [CHAR LIMIT=30] -->
+ <string name="thermal_shutdown_title">Phone turned off due to heat</string>
+ <!-- Message body for notification that user's phone last shut down because it got too hot. [CHAR LIMIT=100] -->
+ <string name="thermal_shutdown_message">Your phone is now running normally</string>
+ <!-- Text body for dialog alerting user that their phone last shut down bewcause it got too hot. [CHAR LIMIT=300] -->
+ <string name="thermal_shutdown_dialog_message">Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n\t• Use resource-intensive apps (such as gaming, video, or navigation apps)\n\t• Download or upload large files\n\t• Use your phone in high temperatures</string>
+
<!-- Title for notification (and dialog) that user's phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=30] -->
<string name="high_temp_title">Phone is getting warm</string>
<!-- Message body for notification that user's phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=100] -->
@@ -1975,13 +1982,13 @@
<string name="dnd_is_off">Do Not Disturb is off</string>
<!-- Prompt for when Do not disturb is on from automatic rule in QS [CHAR LIMIT=NONE] -->
- <string name="qs_dnd_prompt_auto_rule">Do Not Disturb was turned on by an automatic rule (<xliff:g name="rule">%s</xliff:g>). Keep current settings?</string>
+ <string name="qs_dnd_prompt_auto_rule">Do Not Disturb was turned on by an automatic rule (<xliff:g name="rule">%s</xliff:g>).</string>
<!-- Prompt for when Do not disturb is on from app in QS [CHAR LIMIT=NONE] -->
- <string name="qs_dnd_prompt_app">Do Not Disturb was turned on by an app (<xliff:g name="app">%s</xliff:g>). Keep current settings?</string>
+ <string name="qs_dnd_prompt_app">Do Not Disturb was turned on by an app (<xliff:g name="app">%s</xliff:g>).</string>
<!-- Prompt for when Do not disturb is on from automatic rule or app in QS [CHAR LIMIT=NONE] -->
- <string name="qs_dnd_prompt_auto_rule_app">Do Not Disturb was turned on by an automatic rule or app. Keep current settings?</string>
+ <string name="qs_dnd_prompt_auto_rule_app">Do Not Disturb was turned on by an automatic rule or app.</string>
<!-- Description of Do Not Disturb option in QS that ends at the specified time[CHAR LIMIT=20] -->
<string name="qs_dnd_until">Until <xliff:g name="time">%s</xliff:g></string>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index fbb075a..0eb469f 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -158,6 +158,7 @@
* the main process.
* <p>This method must only be called from the main thread.</p>
*/
+
public void startServicesIfNeeded() {
startServicesIfNeeded(SERVICES);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 4e7cf72..c06e56a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -21,11 +21,16 @@
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS;
-import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_MENU;
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MENU_STATE;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS;
+import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
+import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
+import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
@@ -85,7 +90,7 @@
private static final float DISABLED_ACTION_ALPHA = 0.54f;
- private boolean mMenuVisible;
+ private int mMenuState;
private boolean mAllowMenuTimeout = true;
private final List<RemoteAction> mActions = new ArrayList<>();
@@ -98,7 +103,8 @@
private ImageView mExpandButton;
private int mBetweenActionPaddingLand;
- private ObjectAnimator mMenuContainerAnimator;
+ private AnimatorSet mMenuContainerAnimator;
+
private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener =
new ValueAnimator.AnimatorUpdateListener() {
@Override
@@ -119,7 +125,8 @@
switch (msg.what) {
case MESSAGE_SHOW_MENU: {
final Bundle data = (Bundle) msg.obj;
- showMenu(data.getParcelable(EXTRA_STACK_BOUNDS),
+ showMenu(data.getInt(EXTRA_MENU_STATE),
+ data.getParcelable(EXTRA_STACK_BOUNDS),
data.getParcelable(EXTRA_MOVEMENT_BOUNDS),
data.getBoolean(EXTRA_ALLOW_TIMEOUT));
break;
@@ -170,9 +177,14 @@
mMenuContainer = findViewById(R.id.menu_container);
mMenuContainer.setAlpha(0);
mMenuContainer.setOnClickListener((v) -> {
- expandPip();
+ if (mMenuState == MENU_STATE_CLOSE) {
+ showPipMenu();
+ } else {
+ expandPip();
+ }
});
mDismissButton = findViewById(R.id.dismiss);
+ mDismissButton.setAlpha(0);
mDismissButton.setOnClickListener((v) -> {
dismissPip();
});
@@ -236,7 +248,8 @@
break;
case MotionEvent.ACTION_MOVE:
mDownDelta.set(ev.getX() - mDownPosition.x, ev.getY() - mDownPosition.y);
- if (mDownDelta.length() > mViewConfig.getScaledTouchSlop() && mMenuVisible) {
+ if (mDownDelta.length() > mViewConfig.getScaledTouchSlop()
+ && mMenuState != MENU_STATE_NONE) {
// Restore the input consumer and let that drive the movement of this menu
notifyRegisterInputConsumer();
cancelDelayedFinish();
@@ -259,17 +272,28 @@
// Do nothing
}
- private void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) {
+ private void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
+ boolean allowMenuTimeout) {
mAllowMenuTimeout = allowMenuTimeout;
- if (!mMenuVisible) {
+ if (mMenuState != menuState) {
+ cancelDelayedFinish();
updateActionViews(stackBounds);
if (mMenuContainerAnimator != null) {
mMenuContainerAnimator.cancel();
}
- notifyMenuVisibility(true);
+ notifyMenuStateChange(menuState);
updateExpandButtonFromBounds(stackBounds, movementBounds);
- mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
+ mMenuContainerAnimator = new AnimatorSet();
+ ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
mMenuContainer.getAlpha(), 1f);
+ menuAnim.addUpdateListener(mMenuBgUpdateListener);
+ ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
+ mDismissButton.getAlpha(), 1f);
+ if (menuState == MENU_STATE_FULL) {
+ mMenuContainerAnimator.playTogether(menuAnim, dismissAnim);
+ } else {
+ mMenuContainerAnimator.play(dismissAnim);
+ }
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
if (allowMenuTimeout) {
@@ -280,7 +304,6 @@
}
});
}
- mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
mMenuContainerAnimator.start();
} else {
// If we are already visible, then just start the delayed dismiss and unregister any
@@ -297,13 +320,18 @@
}
private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility) {
- if (mMenuVisible) {
+ if (mMenuState != MENU_STATE_NONE) {
cancelDelayedFinish();
if (notifyMenuVisibility) {
- notifyMenuVisibility(false);
+ notifyMenuStateChange(MENU_STATE_NONE);
}
- mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
+ mMenuContainerAnimator = new AnimatorSet();
+ ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
mMenuContainer.getAlpha(), 0f);
+ menuAnim.addUpdateListener(mMenuBgUpdateListener);
+ ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
+ mDismissButton.getAlpha(), 0f);
+ mMenuContainerAnimator.playTogether(menuAnim, dismissAnim);
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
@@ -312,11 +340,9 @@
if (animationFinishedRunnable != null) {
animationFinishedRunnable.run();
}
-
finish();
}
});
- mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
mMenuContainerAnimator.start();
} else {
// If the menu is not visible, just finish now
@@ -332,11 +358,12 @@
mActions.clear();
mActions.addAll(actions.getList());
}
- if (intent.getBooleanExtra(EXTRA_SHOW_MENU, false)) {
+ final int menuState = intent.getIntExtra(EXTRA_MENU_STATE, MENU_STATE_NONE);
+ if (menuState != MENU_STATE_NONE) {
Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS);
Rect movementBounds = intent.getParcelableExtra(EXTRA_MOVEMENT_BOUNDS);
boolean allowMenuTimeout = intent.getBooleanExtra(EXTRA_ALLOW_TIMEOUT, true);
- showMenu(stackBounds, movementBounds, allowMenuTimeout);
+ showMenu(menuState, stackBounds, movementBounds, allowMenuTimeout);
}
}
@@ -372,7 +399,7 @@
return true;
});
- if (mActions.isEmpty()) {
+ if (mActions.isEmpty() || mMenuState == MENU_STATE_CLOSE) {
actionsContainer.setVisibility(View.INVISIBLE);
} else {
actionsContainer.setVisibility(View.VISIBLE);
@@ -427,12 +454,17 @@
private void updateDismissFraction(float fraction) {
int alpha;
- if (mMenuVisible) {
- mMenuContainer.setAlpha(1 - fraction);
+ final float menuAlpha = 1 - fraction;
+ if (mMenuState == MENU_STATE_FULL) {
+ mMenuContainer.setAlpha(menuAlpha);
+ mDismissButton.setAlpha(menuAlpha);
final float interpolatedAlpha =
- MENU_BACKGROUND_ALPHA * (1.0f - fraction) + DISMISS_BACKGROUND_ALPHA * fraction;
+ MENU_BACKGROUND_ALPHA * menuAlpha + DISMISS_BACKGROUND_ALPHA * fraction;
alpha = (int) (interpolatedAlpha * 255);
} else {
+ if (mMenuState == MENU_STATE_CLOSE) {
+ mDismissButton.setAlpha(menuAlpha);
+ }
alpha = (int) (fraction * DISMISS_BACKGROUND_ALPHA * 255);
}
mBackgroundDrawable.setAlpha(alpha);
@@ -450,11 +482,11 @@
sendMessage(m, "Could not notify controller to unregister input consumer");
}
- private void notifyMenuVisibility(boolean visible) {
- mMenuVisible = visible;
+ private void notifyMenuStateChange(int menuState) {
+ mMenuState = menuState;
Message m = Message.obtain();
- m.what = PipMenuActivityController.MESSAGE_MENU_VISIBILITY_CHANGED;
- m.arg1 = visible ? 1 : 0;
+ m.what = PipMenuActivityController.MESSAGE_MENU_STATE_CHANGED;
+ m.arg1 = menuState;
sendMessage(m, "Could not notify controller of PIP menu visibility");
}
@@ -481,6 +513,12 @@
}, false /* notifyMenuVisibility */);
}
+ private void showPipMenu() {
+ Message m = Message.obtain();
+ m.what = PipMenuActivityController.MESSAGE_SHOW_MENU;
+ sendMessage(m, "Could not notify controller to show PIP menu");
+ }
+
private void notifyActivityCallback(Messenger callback) {
Message m = Message.obtain();
m.what = PipMenuActivityController.MESSAGE_UPDATE_ACTIVITY_CALLBACK;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 875fb14..c41f898 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -57,16 +57,21 @@
public static final String EXTRA_STACK_BOUNDS = "stack_bounds";
public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds";
public static final String EXTRA_ALLOW_TIMEOUT = "allow_timeout";
- public static final String EXTRA_SHOW_MENU = "show_menu";
public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction";
+ public static final String EXTRA_MENU_STATE = "menu_state";
- public static final int MESSAGE_MENU_VISIBILITY_CHANGED = 100;
+ public static final int MESSAGE_MENU_STATE_CHANGED = 100;
public static final int MESSAGE_EXPAND_PIP = 101;
public static final int MESSAGE_MINIMIZE_PIP = 102;
public static final int MESSAGE_DISMISS_PIP = 103;
public static final int MESSAGE_UPDATE_ACTIVITY_CALLBACK = 104;
public static final int MESSAGE_REGISTER_INPUT_CONSUMER = 105;
public static final int MESSAGE_UNREGISTER_INPUT_CONSUMER = 106;
+ public static final int MESSAGE_SHOW_MENU = 107;
+
+ public static final int MENU_STATE_NONE = 0;
+ public static final int MENU_STATE_CLOSE = 1;
+ public static final int MENU_STATE_FULL = 2;
/**
* A listener interface to receive notification on changes in PIP.
@@ -75,10 +80,10 @@
/**
* Called when the PIP menu visibility changes.
*
- * @param menuVisible whether or not the menu is visible
- * @param resize whether or not to resize the PiP with the visibility change
+ * @param menuState the current state of the menu
+ * @param resize whether or not to resize the PiP with the state change
*/
- void onPipMenuVisibilityChanged(boolean menuVisible, boolean resize);
+ void onPipMenuStateChanged(int menuState, boolean resize);
/**
* Called when the PIP requested to be expanded.
@@ -94,6 +99,11 @@
* Called when the PIP requested to be dismissed.
*/
void onPipDismiss();
+
+ /**
+ * Called when the PIP requested to show the menu.
+ */
+ void onPipShowMenu();
}
private Context mContext;
@@ -104,7 +114,7 @@
private ArrayList<Listener> mListeners = new ArrayList<>();
private ParceledListSlice mAppActions;
private ParceledListSlice mMediaActions;
- private boolean mMenuVisible;
+ private int mMenuState;
// The dismiss fraction update is sent frequently, so use a temporary bundle for the message
private Bundle mTmpDismissFractionData = new Bundle();
@@ -115,16 +125,16 @@
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case MESSAGE_MENU_VISIBILITY_CHANGED: {
- boolean visible = msg.arg1 > 0;
- onMenuVisibilityChanged(visible, true /* resize */);
+ case MESSAGE_MENU_STATE_CHANGED: {
+ int menuState = msg.arg1;
+ onMenuStateChanged(menuState, true /* resize */);
break;
}
case MESSAGE_EXPAND_PIP: {
mListeners.forEach(l -> l.onPipExpand());
// Preemptively mark the menu as invisible once we expand the PiP, but don't
// resize as we will be animating the stack
- onMenuVisibilityChanged(false, false /* resize */);
+ onMenuStateChanged(MENU_STATE_NONE, false /* resize */);
break;
}
case MESSAGE_MINIMIZE_PIP: {
@@ -135,7 +145,11 @@
mListeners.forEach(l -> l.onPipDismiss());
// Preemptively mark the menu as invisible once we dismiss the PiP, but don't
// resize as we'll be removing the stack in place
- onMenuVisibilityChanged(false, false /* resize */);
+ onMenuStateChanged(MENU_STATE_NONE, false /* resize */);
+ break;
+ }
+ case MESSAGE_SHOW_MENU: {
+ mListeners.forEach(l -> l.onPipShowMenu());
break;
}
case MESSAGE_REGISTER_INPUT_CONSUMER: {
@@ -151,7 +165,7 @@
mStartActivityRequested = false;
// Mark the menu as invisible once the activity finishes as well
if (mToActivityMessenger == null) {
- onMenuVisibilityChanged(false, true /* resize */);
+ onMenuStateChanged(MENU_STATE_NONE, true /* resize */);
}
break;
}
@@ -176,7 +190,7 @@
}
public void onActivityPinned() {
- if (!mMenuVisible) {
+ if (mMenuState == MENU_STATE_NONE) {
// If the menu is not visible, then re-register the input consumer if it is not already
// registered
mInputConsumerController.registerInputConsumer();
@@ -209,23 +223,25 @@
try {
mToActivityMessenger.send(m);
} catch (RemoteException e) {
- Log.e(TAG, "Could not notify menu to show", e);
+ Log.e(TAG, "Could not notify menu to update dismiss fraction", e);
}
} else if (!mStartActivityRequested) {
- startMenuActivity(null /* stackBounds */, null /* movementBounds */,
- false /* showMenu */, false /* allowMenuTimeout */);
+ startMenuActivity(MENU_STATE_NONE, null /* stackBounds */,
+ null /* movementBounds */, false /* allowMenuTimeout */);
}
}
/**
* Shows the menu activity.
*/
- public void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) {
+ public void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
+ boolean allowMenuTimeout) {
if (DEBUG) {
Log.d(TAG, "showMenu() hasActivity=" + (mToActivityMessenger != null));
}
if (mToActivityMessenger != null) {
Bundle data = new Bundle();
+ data.putInt(EXTRA_MENU_STATE, menuState);
data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
data.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds);
data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
@@ -238,7 +254,7 @@
Log.e(TAG, "Could not notify menu to show", e);
}
} else if (!mStartActivityRequested) {
- startMenuActivity(stackBounds, movementBounds, true /* showMenu */, allowMenuTimeout);
+ startMenuActivity(menuState, stackBounds, movementBounds, allowMenuTimeout);
}
}
@@ -279,10 +295,10 @@
}
/**
- * @return whether the menu is currently visible.
+ * @return the current menu state.
*/
- public boolean isMenuVisible() {
- return mMenuVisible;
+ public int getMenuState() {
+ return mMenuState;
}
/**
@@ -306,7 +322,7 @@
/**
* Starts the menu activity on the top task of the pinned stack.
*/
- private void startMenuActivity(Rect stackBounds, Rect movementBounds, boolean showMenu,
+ private void startMenuActivity(int menuState, Rect stackBounds, Rect movementBounds,
boolean allowMenuTimeout) {
try {
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
@@ -321,7 +337,7 @@
if (movementBounds != null) {
intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds);
}
- intent.putExtra(EXTRA_SHOW_MENU, showMenu);
+ intent.putExtra(EXTRA_MENU_STATE, menuState);
intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
options.setLaunchTaskId(
@@ -378,19 +394,19 @@
/**
* Handles changes in menu visibility.
*/
- private void onMenuVisibilityChanged(boolean visible, boolean resize) {
+ private void onMenuStateChanged(int menuState, boolean resize) {
if (DEBUG) {
- Log.d(TAG, "onMenuVisibilityChanged() mMenuVisible=" + mMenuVisible
- + " menuVisible=" + visible + " resize=" + resize);
+ Log.d(TAG, "onMenuStateChanged() mMenuState=" + mMenuState
+ + " menuState=" + menuState + " resize=" + resize);
}
- if (visible) {
- mInputConsumerController.unregisterInputConsumer();
- } else {
+ if (menuState == MENU_STATE_NONE) {
mInputConsumerController.registerInputConsumer();
+ } else {
+ mInputConsumerController.unregisterInputConsumer();
}
- if (visible != mMenuVisible) {
- mListeners.forEach(l -> l.onPipMenuVisibilityChanged(visible, resize));
- if (visible) {
+ if (menuState != mMenuState) {
+ mListeners.forEach(l -> l.onPipMenuStateChanged(menuState, resize));
+ if (menuState == MENU_STATE_FULL) {
// Once visible, start listening for media action changes. This call will trigger
// the menu actions to be updated again.
mMediaController.addListener(mMediaActionListener);
@@ -400,13 +416,13 @@
mMediaController.removeListener(mMediaActionListener);
}
}
- mMenuVisible = visible;
+ mMenuState = menuState;
}
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
- pw.println(innerPrefix + "mMenuVisible=" + mMenuVisible);
+ pw.println(innerPrefix + "mMenuState=" + mMenuState);
pw.println(innerPrefix + "mToActivityMessenger=" + mToActivityMessenger);
pw.println(innerPrefix + "mListeners=" + mListeners.size());
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 161bdac..c3c09a0 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -16,6 +16,10 @@
package com.android.systemui.pip.phone;
+import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
+import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
+import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -106,7 +110,7 @@
private boolean mEnableMinimize = false;
// Behaviour states
- private boolean mIsMenuVisible;
+ private int mMenuState;
private boolean mIsMinimized;
private boolean mIsImeShowing;
private int mImeHeight;
@@ -129,8 +133,8 @@
*/
private class PipMenuListener implements PipMenuActivityController.Listener {
@Override
- public void onPipMenuVisibilityChanged(boolean menuVisible, boolean resize) {
- setMenuVisibilityState(menuVisible, resize);
+ public void onPipMenuStateChanged(int menuState, boolean resize) {
+ setMenuState(menuState, resize);
}
@Override
@@ -152,6 +156,12 @@
MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
METRIC_VALUE_DISMISSED_BY_TAP);
}
+
+ @Override
+ public void onPipShowMenu() {
+ mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+ mMovementBounds, true /* allowMenuTimeout */);
+ }
}
public PipTouchHandler(Context context, IActivityManager activityManager,
@@ -193,20 +203,21 @@
public void showPictureInPictureMenu() {
// Only show the menu if the user isn't currently interacting with the PiP
if (!mTouchState.isUserInteracting()) {
- mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
- false /* allowMenuTimeout */);
+ mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+ mMovementBounds, false /* allowMenuTimeout */);
}
}
public void onActivityPinned() {
// Reset some states once we are pinned
- if (mIsMenuVisible) {
- mIsMenuVisible = false;
- }
+ mMenuState = MENU_STATE_NONE;
+
if (mIsMinimized) {
setMinimizedStateInternal(false);
}
mDismissViewController.destroyDismissTarget();
+ mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
+ mMovementBounds, true /* allowMenuTimeout */);
}
public void onPinnedStackAnimationEnded() {
@@ -266,7 +277,7 @@
// touching the screen
} else {
final Rect bounds = new Rect(animatingBounds);
- final Rect toMovementBounds = mIsMenuVisible
+ final Rect toMovementBounds = mMenuState == MENU_STATE_FULL
? expandedMovementBounds
: normalMovementBounds;
if (mIsImeShowing) {
@@ -293,7 +304,7 @@
// above
mNormalMovementBounds = normalMovementBounds;
mExpandedMovementBounds = expandedMovementBounds;
- updateMovementBounds(mIsMenuVisible);
+ updateMovementBounds(mMenuState);
}
private void onRegistrationChanged(boolean isRegistered) {
@@ -303,8 +314,8 @@
}
private void onAccessibilityShowMenu() {
- mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
- false /* allowMenuTimeout */);
+ mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+ mMovementBounds, false /* allowMenuTimeout */);
}
private boolean handleTouchEvent(MotionEvent ev) {
@@ -336,7 +347,7 @@
case MotionEvent.ACTION_UP: {
// Update the movement bounds again if the state has changed since the user started
// dragging (ie. when the IME shows)
- updateMovementBounds(mIsMenuVisible);
+ updateMovementBounds(mMenuState);
for (PipTouchGesture gesture : mGestures) {
if (gesture.onUp(mTouchState)) {
@@ -378,7 +389,7 @@
break;
}
}
- return !mIsMenuVisible;
+ return mMenuState == MENU_STATE_NONE;
}
/**
@@ -393,7 +404,7 @@
final float distance = bounds.bottom - target;
fraction = Math.min(distance / bounds.height(), 1f);
}
- if (Float.compare(fraction, 0f) != 0 || mMenuController.isMenuVisible()) {
+ if (Float.compare(fraction, 0f) != 0 || mMenuState != MENU_STATE_NONE) {
// Update if the fraction > 0, or if fraction == 0 and the menu was already visible
mMenuController.setDismissFraction(fraction);
}
@@ -449,8 +460,8 @@
/**
* Sets the menu visibility.
*/
- void setMenuVisibilityState(boolean menuVisible, boolean resize) {
- if (menuVisible) {
+ void setMenuState(int menuState, boolean resize) {
+ if (menuState == MENU_STATE_FULL) {
// Save the current snap fraction and if we do not drag or move the PiP, then
// we store back to this snap fraction. Otherwise, we'll reset the snap
// fraction and snap to the closest edge
@@ -459,7 +470,7 @@
mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
mMovementBounds, mExpandedMovementBounds);
}
- } else {
+ } else if (menuState == MENU_STATE_NONE) {
// Try and restore the PiP to the closest edge, using the saved snap fraction
// if possible
if (resize) {
@@ -469,10 +480,12 @@
}
mSavedSnapFraction = -1f;
}
- mIsMenuVisible = menuVisible;
- updateMovementBounds(menuVisible);
- MetricsLogger.visibility(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MENU,
- menuVisible);
+ mMenuState = menuState;
+ updateMovementBounds(menuState);
+ if (menuState != MENU_STATE_CLOSE) {
+ MetricsLogger.visibility(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MENU,
+ menuState == MENU_STATE_FULL);
+ }
}
/**
@@ -501,7 +514,7 @@
// If the menu is still visible, and we aren't minimized, then just poke the menu
// so that it will timeout after the user stops touching it
- if (mMenuController.isMenuVisible() && !mIsMinimized) {
+ if (mMenuState != MENU_STATE_NONE && !mIsMinimized) {
mMenuController.pokeMenu();
}
@@ -599,7 +612,7 @@
!mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) {
// Pip should be minimized
setMinimizedStateInternal(true);
- if (mMenuController.isMenuVisible()) {
+ if (mMenuState == MENU_STATE_FULL) {
// If the user dragged the expanded PiP to the edge, then hiding the menu
// will trigger the PiP to be scaled back to the normal size with the
// minimize offset adjusted
@@ -617,11 +630,11 @@
}
AnimatorListenerAdapter postAnimationCallback = null;
- if (mMenuController.isMenuVisible()) {
+ if (mMenuState != MENU_STATE_NONE) {
// If the menu is still visible, and we aren't minimized, then just poke the
// menu so that it will timeout after the user stops touching it
- mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
- true /* allowMenuTimeout */);
+ mMenuController.showMenu(mMenuState, mMotionHelper.getBounds(),
+ mMovementBounds, true /* allowMenuTimeout */);
} else {
// If the menu is not visible, then we can still be showing the activity for the
// dismiss overlay, so just finish it after the animation completes
@@ -645,9 +658,9 @@
mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* updateListener */,
null /* animatorListener */);
setMinimizedStateInternal(false);
- } else if (!mIsMenuVisible) {
- mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
- true /* allowMenuTimeout */);
+ } else if (mMenuState != MENU_STATE_FULL) {
+ mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+ mMovementBounds, true /* allowMenuTimeout */);
} else {
mMotionHelper.expandPip();
}
@@ -658,8 +671,8 @@
/**
* Updates the current movement bounds based on whether the menu is currently visible.
*/
- private void updateMovementBounds(boolean isExpanded) {
- mMovementBounds = isExpanded
+ private void updateMovementBounds(int menuState) {
+ mMovementBounds = menuState == MENU_STATE_FULL
? mExpandedMovementBounds
: mNormalMovementBounds;
}
@@ -672,7 +685,7 @@
pw.println(innerPrefix + "mNormalMovementBounds=" + mNormalMovementBounds);
pw.println(innerPrefix + "mExpandedBounds=" + mExpandedBounds);
pw.println(innerPrefix + "mExpandedMovementBounds=" + mExpandedMovementBounds);
- pw.println(innerPrefix + "mIsMenuVisible=" + mIsMenuVisible);
+ pw.println(innerPrefix + "mMenuState=" + mMenuState);
pw.println(innerPrefix + "mIsMinimized=" + mIsMinimized);
pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
index 65238b1..efc0668 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
@@ -81,8 +81,8 @@
mItemList.setAdapter(mAdapter);
mEmpty = findViewById(android.R.id.empty);
mEmpty.setVisibility(GONE);
- mEmptyText = (TextView) mEmpty.findViewById(android.R.id.title);
- mEmptyIcon = (ImageView) mEmpty.findViewById(android.R.id.icon);
+ mEmptyText = mEmpty.findViewById(android.R.id.title);
+ mEmptyIcon = mEmpty.findViewById(android.R.id.icon);
}
@Override
@@ -104,8 +104,10 @@
}
public void setEmptyState(int icon, int text) {
- mEmptyIcon.setImageResource(icon);
- mEmptyText.setText(text);
+ mEmptyIcon.post(() -> {
+ mEmptyIcon.setImageResource(icon);
+ mEmptyText.setText(text);
+ });
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 2e6116dba..38485c7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -32,6 +32,7 @@
import android.widget.LinearLayout;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.DetailAdapter;
@@ -118,7 +119,8 @@
protected void addDivider() {
mDivider = LayoutInflater.from(mContext).inflate(R.layout.qs_divider, this, false);
- mDivider.setBackgroundColor(getColorForState(mContext, Tile.STATE_INACTIVE));
+ mDivider.setBackgroundColor(Utils.applyAlpha(mDivider.getAlpha(),
+ getColorForState(mContext, Tile.STATE_ACTIVE)));
addView(mDivider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index d0d6f61..7518527a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -21,15 +21,19 @@
import android.graphics.Rect;
import android.support.annotation.VisibleForTesting;
import android.util.AttributeSet;
+import android.view.View;
import android.widget.RelativeLayout;
+import android.widget.TextClock;
import com.android.settingslib.Utils;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.R.id;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.qs.QSDetail.Callback;
import com.android.systemui.statusbar.SignalClusterView;
+import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
public class QuickStatusBarHeader extends RelativeLayout {
@@ -63,19 +67,27 @@
updateResources();
// Set the light/dark theming on the header status UI to match the current theme.
- SignalClusterView cluster = findViewById(R.id.signal_cluster);
int colorForeground = Utils.getColorAttr(getContext(), android.R.attr.colorForeground);
float intensity = colorForeground == Color.WHITE ? 0 : 1;
- cluster.onDarkChanged(new Rect(0, 0, 0, 0), intensity, colorForeground);
+ Rect tintArea = new Rect(0, 0, 0, 0);
+
+ applyDarkness(R.id.signal_cluster, tintArea, intensity, colorForeground);
+ applyDarkness(R.id.battery, tintArea, intensity, colorForeground);
+ applyDarkness(R.id.clock, tintArea, intensity, colorForeground);
BatteryMeterView battery = findViewById(R.id.battery);
battery.setForceShowPercent(true);
- int colorSecondary = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary);
- battery.setRawColors(colorForeground, colorSecondary);
mActivityStarter = Dependency.get(ActivityStarter.class);
}
+ private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
+ View v = findViewById(id);
+ if (v instanceof DarkReceiver) {
+ ((DarkReceiver) v).onDarkChanged(tintArea, intensity, color);
+ }
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 1aa51b1..6781c16 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -22,6 +22,7 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import android.R.attr;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
@@ -73,6 +74,7 @@
private String mTileSpec;
private EnforcedAdmin mEnforcedAdmin;
+ private boolean mShowingDetail;
public abstract TState newTileState();
@@ -286,11 +288,16 @@
}
private void handleShowDetail(boolean show) {
+ mShowingDetail = show;
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onShowDetail(show);
}
}
+ protected boolean isShowingDetail() {
+ return mShowingDetail;
+ }
+
private void handleToggleStateChanged(boolean state) {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onToggleStateChanged(state);
@@ -336,9 +343,9 @@
Utils.getColorAttr(context, android.R.attr.textColorTertiary));
case Tile.STATE_INACTIVE:
return Utils.getDisabled(context,
- Utils.getColorAttr(context, android.R.attr.colorForeground));
+ Utils.getColorAttr(context, android.R.attr.textColorSecondary));
case Tile.STATE_ACTIVE:
- return Utils.getColorAttr(context, android.R.attr.colorForeground);
+ return Utils.getColorAttr(context, attr.textColorSecondary);
default:
Log.e("QSTile", "Invalid state " + state);
return 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
index 5c998090..263dac0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
@@ -42,6 +42,7 @@
private int mState;
private ViewGroup mLabelContainer;
private View mExpandIndicator;
+ private View mExpandSpace;
public QSTileView(Context context, QSIconView icon) {
this(context, icon, false);
@@ -84,6 +85,7 @@
mPadLock = mLabelContainer.findViewById(R.id.restricted_padlock);
mDivider = mLabelContainer.findViewById(R.id.underline);
mExpandIndicator = mLabelContainer.findViewById(R.id.expand_indicator);
+ mExpandSpace = mLabelContainer.findViewById(R.id.expand_space);
addView(mLabelContainer);
}
@@ -101,8 +103,8 @@
mState = state.state;
mLabel.setText(state.label);
}
- mDivider.setVisibility(state.dualTarget ? View.VISIBLE : View.INVISIBLE);
mExpandIndicator.setVisibility(state.dualTarget ? View.VISIBLE : View.GONE);
+ mExpandSpace.setVisibility(state.dualTarget ? View.VISIBLE : View.GONE);
mLabelContainer.setContentDescription(state.dualTarget ? state.dualLabelContentDescription
: null);
if (state.dualTarget != mLabelContainer.isClickable()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 75e9d5a..d27bb85 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -35,10 +35,10 @@
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSDetailItems;
import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost;
-import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BluetoothController;
@@ -99,10 +99,6 @@
return;
}
showDetail(true);
- if (!mState.value) {
- mState.value = true;
- mController.setBluetoothEnabled(true);
- }
}
@Override
@@ -176,6 +172,9 @@
@Override
public void onBluetoothStateChange(boolean enabled) {
refreshState();
+ if (isShowingDetail()) {
+ mDetailAdapter.updateItems();
+ }
}
@Override
@@ -187,6 +186,9 @@
}
});
refreshState();
+ if (isShowingDetail()) {
+ mDetailAdapter.updateItems();
+ }
}
};
@@ -223,7 +225,6 @@
public void setToggleState(boolean state) {
MetricsLogger.action(mContext, MetricsEvent.QS_BLUETOOTH_TOGGLE, state);
mController.setBluetoothEnabled(state);
- showDetail(false);
}
@Override
@@ -235,8 +236,6 @@
public View createDetailView(Context context, View convertView, ViewGroup parent) {
mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
mItems.setTagSuffix("Bluetooth");
- mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
- R.string.quick_settings_bluetooth_detail_empty_text);
mItems.setCallback(this);
updateItems();
setItemsVisible(mState.value);
@@ -250,6 +249,13 @@
private void updateItems() {
if (mItems == null) return;
+ if (mController.isBluetoothEnabled()) {
+ mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
+ R.string.quick_settings_bluetooth_detail_empty_text);
+ } else {
+ mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
+ R.string.bt_is_off);
+ }
ArrayList<Item> items = new ArrayList<Item>();
final Collection<CachedBluetoothDevice> devices = mController.getDevices();
if (devices != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 3c2e897..ecbc4f76 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -16,16 +16,25 @@
package com.android.systemui.qs.tiles;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeConfig.ZenRule;
import android.service.quicksettings.Tile;
+import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
@@ -41,9 +50,9 @@
import com.android.systemui.SysUIToast;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
-import com.android.systemui.qs.QSHost;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.volume.ZenModePanel;
@@ -129,10 +138,9 @@
@Override
protected void handleClick() {
if (mState.value) {
- mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
+ mController.setZen(ZEN_MODE_OFF, null, TAG);
} else {
- int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
- mController.setZen(zen, null, TAG);
+ mController.setZen(ZEN_MODE_ALARMS, null, TAG);
}
}
@@ -147,8 +155,6 @@
return;
}
showDetail(true);
- int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
- mController.setZen(zen, null, TAG);
}
@Override
@@ -159,7 +165,7 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
- final boolean newValue = zen != Global.ZEN_MODE_OFF;
+ final boolean newValue = zen != ZEN_MODE_OFF;
final boolean valueChanged = state.value != newValue;
state.dualTarget = true;
state.value = newValue;
@@ -178,7 +184,7 @@
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_dnd_none_on);
break;
- case Global.ZEN_MODE_ALARMS:
+ case ZEN_MODE_ALARMS:
state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
state.label = mContext.getString(R.string.quick_settings_dnd_alarms_label);
state.contentDescription = mContext.getString(
@@ -187,13 +193,10 @@
default:
state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
state.label = mContext.getString(R.string.quick_settings_dnd_label);
- state.contentDescription = mContext.getString(
+ state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_dnd);
break;
}
- if (mShowingDetail && !state.value) {
- showDetail(false);
- }
if (valueChanged) {
fireToggleStateChanged(state.value);
}
@@ -249,6 +252,16 @@
private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
public void onZenChanged(int zen) {
refreshState(zen);
+ if (isShowingDetail()) {
+ mDetailAdapter.updatePanel();
+ }
+ }
+
+ @Override
+ public void onConfigChanged(ZenModeConfig config) {
+ if (isShowingDetail()) {
+ mDetailAdapter.updatePanel();
+ }
}
};
@@ -263,6 +276,9 @@
private final class DndDetailAdapter implements DetailAdapter, OnAttachStateChangeListener {
+ private ZenModePanel mZenPanel;
+ private boolean mAuto;
+
@Override
public CharSequence getTitle() {
return mContext.getString(R.string.quick_settings_dnd_label);
@@ -282,8 +298,12 @@
public void setToggleState(boolean state) {
MetricsLogger.action(mContext, MetricsEvent.QS_DND_TOGGLE, state);
if (!state) {
- mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
- showDetail(false);
+ mController.setZen(ZEN_MODE_OFF, null, TAG);
+ mAuto = false;
+ } else {
+ int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN,
+ ZEN_MODE_ALARMS);
+ mController.setZen(zen, null, TAG);
}
}
@@ -294,15 +314,65 @@
@Override
public View createDetailView(Context context, View convertView, ViewGroup parent) {
- final ZenModePanel zmp = convertView != null ? (ZenModePanel) convertView
+ mZenPanel = convertView != null ? (ZenModePanel) convertView
: (ZenModePanel) LayoutInflater.from(context).inflate(
R.layout.zen_mode_panel, parent, false);
if (convertView == null) {
- zmp.init(mController);
- zmp.addOnAttachStateChangeListener(this);
- zmp.setCallback(mZenModePanelCallback);
+ mZenPanel.init(mController);
+ mZenPanel.addOnAttachStateChangeListener(this);
+ mZenPanel.setCallback(mZenModePanelCallback);
+ mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_off, R.string.dnd_is_off);
}
- return zmp;
+ updatePanel();
+ return mZenPanel;
+ }
+
+ private void updatePanel() {
+ if (mZenPanel == null) return;
+ mAuto = false;
+ if (mController.getZen() == ZEN_MODE_OFF) {
+ mZenPanel.setState(ZenModePanel.STATE_OFF);
+ } else {
+ ZenModeConfig config = mController.getConfig();
+ String summary = "";
+ if (config.manualRule != null && config.manualRule.enabler != null) {
+ summary = getOwnerCaption(config.manualRule.enabler);
+ }
+ for (ZenRule automaticRule : config.automaticRules.values()) {
+ if (automaticRule.isAutomaticActive()) {
+ if (summary.isEmpty()) {
+ summary = mContext.getString(R.string.qs_dnd_prompt_auto_rule,
+ automaticRule.name);
+ } else {
+ summary = mContext.getString(R.string.qs_dnd_prompt_auto_rule_app);
+ }
+ }
+ }
+ if (summary.isEmpty()) {
+ mZenPanel.setState(ZenModePanel.STATE_MODIFY);
+ } else {
+ mAuto = true;
+ mZenPanel.setState(ZenModePanel.STATE_AUTO_RULE);
+ mZenPanel.setAutoText(summary);
+ }
+ }
+ }
+
+ private String getOwnerCaption(String owner) {
+ final PackageManager pm = mContext.getPackageManager();
+ try {
+ final ApplicationInfo info = pm.getApplicationInfo(owner, 0);
+ if (info != null) {
+ final CharSequence seq = info.loadLabel(pm);
+ if (seq != null) {
+ final String str = seq.toString().trim();
+ return mContext.getString(R.string.qs_dnd_prompt_app, str);
+ }
+ }
+ } catch (Throwable e) {
+ Slog.w(TAG, "Error loading owner caption", e);
+ }
+ return "";
}
@Override
@@ -313,6 +383,7 @@
@Override
public void onViewDetachedFromWindow(View v) {
mShowingDetail = false;
+ mZenPanel = null;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 7d2d210..5a23d3b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -32,6 +32,7 @@
import com.android.settingslib.wifi.AccessPoint;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.R.string;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSDetailItems;
@@ -98,7 +99,9 @@
}
@Override
- protected DetailAdapter createDetailAdapter() { return new WifiDetailAdapter(); }
+ protected DetailAdapter createDetailAdapter() {
+ return new WifiDetailAdapter();
+ }
@Override
public QSIconView createTileView(Context context) {
@@ -125,10 +128,6 @@
return;
}
showDetail(true);
- if (!mState.value) {
- mController.setWifiEnabled(true);
- mState.value = true;
- }
}
@Override
@@ -234,15 +233,15 @@
@Override
public String toString() {
return new StringBuilder("CallbackInfo[")
- .append("enabled=").append(enabled)
- .append(",connected=").append(connected)
- .append(",wifiSignalIconId=").append(wifiSignalIconId)
- .append(",enabledDesc=").append(enabledDesc)
- .append(",activityIn=").append(activityIn)
- .append(",activityOut=").append(activityOut)
- .append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
- .append(",isTransient=").append(isTransient)
- .append(']').toString();
+ .append("enabled=").append(enabled)
+ .append(",connected=").append(connected)
+ .append(",wifiSignalIconId=").append(wifiSignalIconId)
+ .append(",enabledDesc=").append(enabledDesc)
+ .append(",activityIn=").append(activityIn)
+ .append(",activityOut=").append(activityOut)
+ .append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
+ .append(",isTransient=").append(isTransient)
+ .append(']').toString();
}
}
@@ -261,9 +260,14 @@
mInfo.activityOut = activityOut;
mInfo.wifiSignalContentDescription = qsIcon.contentDescription;
mInfo.isTransient = isTransient;
+ if (isShowingDetail()) {
+ mDetailAdapter.updateItems();
+ }
refreshState(mInfo);
}
- };
+ }
+
+ ;
protected class WifiDetailAdapter implements DetailAdapter,
NetworkController.AccessPointController.AccessPointCallback, QSDetailItems.Callback {
@@ -290,7 +294,6 @@
if (DEBUG) Log.d(TAG, "setToggleState " + state);
MetricsLogger.action(mContext, MetricsEvent.QS_WIFI_TOGGLE, state);
mController.setWifiEnabled(state);
- showDetail(false);
}
@Override
@@ -307,8 +310,6 @@
mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
mItems.setTagSuffix("Wifi");
mItems.setCallback(this);
- mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
- R.string.quick_settings_wifi_detail_empty_text);
updateItems();
setItemsVisible(mState.value);
return mItems;
@@ -352,6 +353,13 @@
private void updateItems() {
if (mItems == null) return;
+ if (mSignalCallback.mInfo.enabled) {
+ mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
+ R.string.quick_settings_wifi_detail_empty_text);
+ } else {
+ mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
+ R.string.wifi_is_off);
+ }
Item[] items = null;
if (mAccessPoints != null) {
items = new Item[mAccessPoints.length];
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 9176f57..677642e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -328,6 +328,9 @@
mIsColorized = mStatusBarNotification.getNotification().isColorized();
mShowingPublicInitialized = false;
updateNotificationColor();
+ if (mMenuRow != null) {
+ mMenuRow.onNotificationUpdated();
+ }
if (mIsSummaryWithChildren) {
mChildrenContainer.recreateNotificationHeader(mExpandClickListener);
mChildrenContainer.onNotificationUpdated();
@@ -760,7 +763,10 @@
}
mMenuRow = plugin;
if (mMenuRow.useDefaultMenuItems()) {
- mMenuRow.setMenuItems(NotificationMenuRow.getDefaultMenuItems(mContext));
+ ArrayList<MenuItem> items = new ArrayList<>();
+ items.add(NotificationMenuRow.createInfoItem(mContext));
+ items.add(NotificationMenuRow.createSnoozeItem(mContext));
+ mMenuRow.setMenuItems(items);
}
if (existed) {
createMenu();
@@ -787,7 +793,6 @@
return mMenuRow;
}
-
public NotificationMenuRowPlugin getProvider() {
return mMenuRow;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index bb82b60..2a1e063 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -30,11 +30,13 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.app.Notification;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.Log;
+import android.service.notification.StatusBarNotification;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -48,12 +50,12 @@
private static final long SHOW_MENU_DELAY = 60;
private static final long SWIPE_MENU_TIMING = 200;
- private static final int NOTIFICATION_INFO_INDEX = 1;
-
private ExpandableNotificationRow mParent;
private Context mContext;
private FrameLayout mMenuContainer;
+ private MenuItem mSnoozeItem;
+ private MenuItem mInfoItem;
private ArrayList<MenuItem> mMenuItems;
private OnMenuEventListener mMenuListener;
@@ -94,7 +96,11 @@
mVertSpaceForIcons = res.getDimensionPixelSize(R.dimen.notification_min_height);
mIconPadding = res.getDimensionPixelSize(R.dimen.notification_menu_icon_padding);
mHandler = new Handler();
- mMenuItems = getDefaultMenuItems(context);
+ mMenuItems = new ArrayList<>();
+ mSnoozeItem = createSnoozeItem(context);
+ mInfoItem = createInfoItem(context);
+ mMenuItems.add(mSnoozeItem);
+ mMenuItems.add(mInfoItem);
}
@Override
@@ -104,7 +110,7 @@
@Override
public MenuItem getLongpressMenuItem(Context context) {
- return mMenuItems.get(NOTIFICATION_INFO_INDEX);
+ return mInfoItem;
}
@Override
@@ -120,14 +126,7 @@
@Override
public void createMenu(ViewGroup parent) {
mParent = (ExpandableNotificationRow) parent;
- if (mMenuContainer != null) {
- mMenuContainer.removeAllViews();
- }
- mMenuContainer = new FrameLayout(mContext);
- for (int i = 0; i < mMenuItems.size(); i++) {
- addMenuView(mMenuItems.get(i), mMenuContainer);
- }
- resetState(false);
+ createMenuViews();
}
@Override
@@ -145,6 +144,40 @@
resetState(true);
}
+ @Override
+ public void onNotificationUpdated() {
+ if (mMenuContainer == null) {
+ // Menu hasn't been created yet, no need to do anything.
+ return;
+ }
+ createMenuViews();
+ }
+
+ private void createMenuViews() {
+ // Filter the menu items based on the notification
+ if (mParent != null && mParent.getStatusBarNotification() != null) {
+ int flags = mParent.getStatusBarNotification().getNotification().flags;
+ boolean isForeground = (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
+ if (isForeground) {
+ // Don't show snooze for foreground services
+ mMenuItems.remove(mSnoozeItem);
+ } else if (!mMenuItems.contains(mSnoozeItem)) {
+ // Was a foreground service but is no longer, add snooze back
+ mMenuItems.add(mSnoozeItem);
+ }
+ }
+ // Recreate the menu
+ if (mMenuContainer != null) {
+ mMenuContainer.removeAllViews();
+ } else {
+ mMenuContainer = new FrameLayout(mContext);
+ }
+ for (int i = 0; i < mMenuItems.size(); i++) {
+ addMenuView(mMenuItems.get(i), mMenuContainer);
+ }
+ resetState(false /* notify */);
+ }
+
private void resetState(boolean notify) {
setMenuAlpha(0f);
mIconsPlaced = false;
@@ -495,24 +528,24 @@
// TODO -- handle / allow custom menu items!
}
- public static ArrayList<MenuItem> getDefaultMenuItems(Context context) {
- ArrayList<MenuItem> items = new ArrayList<MenuItem>();
+ public static MenuItem createSnoozeItem(Context context) {
Resources res = context.getResources();
-
NotificationSnooze content = (NotificationSnooze) LayoutInflater.from(context)
.inflate(R.layout.notification_snooze, null, false);
String snoozeDescription = res.getString(R.string.notification_menu_snooze_description);
MenuItem snooze = new NotificationMenuItem(context, snoozeDescription, content,
R.drawable.ic_snooze);
- items.add(snooze);
+ return snooze;
+ }
- String settingsDescription = res.getString(R.string.notification_menu_gear_description);
- NotificationInfo settingsContent = (NotificationInfo) LayoutInflater.from(context).inflate(
+ public static MenuItem createInfoItem(Context context) {
+ Resources res = context.getResources();
+ String infoDescription = res.getString(R.string.notification_menu_gear_description);
+ NotificationInfo infoContent = (NotificationInfo) LayoutInflater.from(context).inflate(
R.layout.notification_info, null, false);
- MenuItem settings = new NotificationMenuItem(context, settingsDescription, settingsContent,
+ MenuItem info = new NotificationMenuItem(context, infoDescription, infoContent,
R.drawable.ic_settings);
- items.add(settings);
- return items;
+ return info;
}
private void addMenuView(MenuItem item, ViewGroup parent) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 1f03024..7562399 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -145,7 +145,7 @@
getContext().getMainThreadHandler());
mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED), false,
- mMagnificationObserver);
+ mMagnificationObserver, UserHandle.USER_ALL);
if (savedInstanceState != null) {
mDisabledFlags1 = savedInstanceState.getInt(EXTRA_DISABLE_STATE, 0);
@@ -559,20 +559,23 @@
private boolean onAccessibilityLongClick(View v) {
Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- v.getContext().startActivity(intent);
+ v.getContext().startActivityAsUser(intent, UserHandle.CURRENT);
return true;
}
private void updateAccessibilityServicesState() {
int requestingServices = 0;
try {
- if (Settings.Secure.getInt(mContentResolver,
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED) == 1) {
+ if (Settings.Secure.getIntForUser(mContentResolver,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
+ UserHandle.USER_CURRENT) == 1) {
requestingServices++;
}
} catch (Settings.SettingNotFoundException e) {
}
+ // AccessibilityManagerService resolves services for the current user since the local
+ // AccessibilityManager is created from a Context with the INTERACT_ACROSS_USERS permission
final List<AccessibilityServiceInfo> services =
mAccessibilityManager.getEnabledAccessibilityServiceList(
AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 9304de5..d3cb6a4a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -6369,17 +6369,10 @@
.getIdentifier();
if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
&& mKeyguardManager.isDeviceLocked(userId)) {
- boolean canBypass = false;
- try {
- canBypass = ActivityManager.getService()
- .canBypassWorkChallenge(intent);
- } catch (RemoteException e) {
- }
- // For direct-boot aware activities, they can be shown when
- // the device is still locked without triggering the work
- // challenge.
- if ((!canBypass) && startWorkChallengeIfNecessary(userId,
- intent.getIntentSender(), notificationKey)) {
+ // TODO(b/28935539): should allow certain activities to
+ // bypass work challenge
+ if (startWorkChallengeIfNecessary(userId,
+ intent.getIntentSender(), notificationKey)) {
// Show work challenge, do not run PendingIntent and
// remove notification
return;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index cfe16dd..c3a53de 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -387,7 +387,7 @@
.addAction(new Action(R.drawable.ic_eject_24dp,
mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
- .setContentIntent(buildUnmountPendingIntent(vol))
+ .setContentIntent(browseIntent)
.setCategory(Notification.CATEGORY_SYSTEM);
// Non-adoptable disks can't be snoozed.
if (disk.isAdoptable()) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 98e89e4..f7dfc0a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -36,6 +36,7 @@
import android.service.notification.ZenModeConfig.ZenRule;
import android.text.TextUtils;
import android.text.format.DateFormat;
+import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
@@ -45,6 +46,7 @@
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
@@ -55,6 +57,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.R.string;
import com.android.systemui.statusbar.policy.ZenModeController;
import java.io.FileDescriptor;
@@ -65,10 +68,14 @@
import java.util.Locale;
import java.util.Objects;
-public class ZenModePanel extends LinearLayout {
+public class ZenModePanel extends FrameLayout {
private static final String TAG = "ZenModePanel";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ public static final int STATE_MODIFY = 0;
+ public static final int STATE_AUTO_RULE = 1;
+ public static final int STATE_OFF = 2;
+
private static final int SECONDS_MS = 1000;
private static final int MINUTES_MS = 60 * SECONDS_MS;
@@ -86,6 +93,8 @@
public static final Intent ZEN_PRIORITY_SETTINGS
= new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
+ private static final long TRANSITION_DURATION = 300;
+
private final Context mContext;
protected final LayoutInflater mInflater;
private final H mHandler = new H();
@@ -124,6 +133,13 @@
protected int mZenModeConditionLayoutId;
protected int mZenModeButtonLayoutId;
+ private View mEmpty;
+ private TextView mEmptyText;
+ private ImageView mEmptyIcon;
+ private View mAutoRule;
+ private TextView mAutoTitle;
+ private int mState = STATE_MODIFY;
+ private ViewGroup mEdit;
public ZenModePanel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -156,7 +172,7 @@
}
protected void createZenButtons() {
- mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons);
+ mZenButtons = findViewById(R.id.zen_buttons);
mZenButtons.addButton(R.string.interruption_level_none_twoline,
R.string.interruption_level_none_with_warning,
Global.ZEN_MODE_NO_INTERRUPTIONS);
@@ -174,30 +190,75 @@
super.onFinishInflate();
createZenButtons();
mZenIntroduction = findViewById(R.id.zen_introduction);
- mZenIntroductionMessage = (TextView) findViewById(R.id.zen_introduction_message);
+ mZenIntroductionMessage = findViewById(R.id.zen_introduction_message);
mZenIntroductionConfirm = findViewById(R.id.zen_introduction_confirm);
- mZenIntroductionConfirm.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- confirmZenIntroduction();
- }
- });
- mZenIntroductionCustomize = (TextView) findViewById(R.id.zen_introduction_customize);
- mZenIntroductionCustomize.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- confirmZenIntroduction();
- if (mCallback != null) {
- mCallback.onPrioritySettings();
- }
+ mZenIntroductionConfirm.setOnClickListener(v -> confirmZenIntroduction());
+ mZenIntroductionCustomize = findViewById(R.id.zen_introduction_customize);
+ mZenIntroductionCustomize.setOnClickListener(v -> {
+ confirmZenIntroduction();
+ if (mCallback != null) {
+ mCallback.onPrioritySettings();
}
});
mConfigurableTexts.add(mZenIntroductionCustomize, R.string.zen_priority_customize_button);
- mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
- mZenAlarmWarning = (TextView) findViewById(R.id.zen_alarm_warning);
- mZenRadioGroup = (RadioGroup) findViewById(R.id.zen_radio_buttons);
- mZenRadioGroupContent = (LinearLayout) findViewById(R.id.zen_radio_buttons_content);
+ mZenConditions = findViewById(R.id.zen_conditions);
+ mZenAlarmWarning = findViewById(R.id.zen_alarm_warning);
+ mZenRadioGroup = findViewById(R.id.zen_radio_buttons);
+ mZenRadioGroupContent = findViewById(R.id.zen_radio_buttons_content);
+
+ mEdit = findViewById(R.id.edit_container);
+
+ mEmpty = findViewById(android.R.id.empty);
+ mEmpty.setVisibility(INVISIBLE);
+ mEmptyText = mEmpty.findViewById(android.R.id.title);
+ mEmptyIcon = mEmpty.findViewById(android.R.id.icon);
+
+ mAutoRule = findViewById(R.id.auto_rule);
+ mAutoTitle = mAutoRule.findViewById(android.R.id.title);
+ mAutoRule.setVisibility(INVISIBLE);
+ }
+
+ public void setEmptyState(int icon, int text) {
+ mEmptyIcon.post(() -> {
+ mEmptyIcon.setImageResource(icon);
+ mEmptyText.setText(text);
+ });
+ }
+
+ public void setAutoText(CharSequence text) {
+ mAutoTitle.post(() -> mAutoTitle.setText(text));
+ }
+
+ public void setState(int state) {
+ if (mState == state) return;
+ transitionFrom(getView(mState), getView(state));
+ mState = state;
+ }
+
+ private void transitionFrom(View from, View to) {
+ from.post(() -> {
+ // TODO: Better transitions
+ to.setAlpha(0);
+ to.setVisibility(VISIBLE);
+ to.bringToFront();
+ to.animate().cancel();
+ to.animate().alpha(1)
+ .setDuration(TRANSITION_DURATION)
+ .withEndAction(() -> from.setVisibility(INVISIBLE))
+ .start();
+ });
+ }
+
+ private View getView(int state) {
+ switch (state) {
+ case STATE_AUTO_RULE:
+ return mAutoRule;
+ case STATE_OFF:
+ return mEmpty;
+ default:
+ return mEdit;
+ }
}
@Override
@@ -232,6 +293,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (DEBUG) Log.d(mTag, "onAttachedToWindow");
+ setExpanded(true);
mAttached = true;
mAttachedZen = getSelectedZen(-1);
mSessionZen = mAttachedZen;
@@ -246,6 +308,7 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (DEBUG) Log.d(mTag, "onDetachedFromWindow");
+ setExpanded(false);
checkForAttachedZenChange();
mAttached = false;
mAttachedZen = -1;
@@ -285,7 +348,7 @@
if (expanded == mExpanded) return;
if (DEBUG) Log.d(mTag, "setExpanded " + expanded);
mExpanded = expanded;
- if (mExpanded && isShown()) {
+ if (mExpanded) {
ensureSelection();
}
updateWidgets();
@@ -317,10 +380,10 @@
protected void addZenConditions(int count) {
for (int i = 0; i < count; i++) {
- final View rb = mInflater.inflate(mZenModeButtonLayoutId, this, false);
+ final View rb = mInflater.inflate(mZenModeButtonLayoutId, mEdit, false);
rb.setId(i);
mZenRadioGroup.addView(rb);
- final View rbc = mInflater.inflate(mZenModeConditionLayoutId, this, false);
+ final View rbc = mInflater.inflate(mZenModeConditionLayoutId, mEdit, false);
rbc.setId(i + count);
mZenRadioGroupContent.addView(rbc);
}
@@ -368,13 +431,26 @@
private void handleUpdateManualRule(ZenRule rule) {
final int zen = rule != null ? rule.zenMode : Global.ZEN_MODE_OFF;
handleUpdateZen(zen);
- final Condition c = rule != null ? rule.condition : null;
+ final Condition c = rule == null ? null
+ : rule.condition != null ? rule.condition
+ : createCondition(rule.conditionId);
handleExitConditionChanged(c);
}
+ private Condition createCondition(Uri conditionId) {
+ if (ZenModeConfig.isValidCountdownConditionId(conditionId)) {
+ long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+ int mins = (int) ((time - System.currentTimeMillis() + DateUtils.MINUTE_IN_MILLIS / 2)
+ / DateUtils.MINUTE_IN_MILLIS);
+ Condition c = ZenModeConfig.toTimeCondition(mContext, time, mins,
+ ActivityManager.getCurrentUser(), false);
+ return c;
+ }
+ return null;
+ }
+
private void handleUpdateZen(int zen) {
if (mSessionZen != -1 && mSessionZen != zen) {
- setExpanded(isShown());
mSessionZen = zen;
}
mZenButtons.setSelectedValue(zen, false /* fromClick */);
@@ -391,15 +467,20 @@
private void handleExitConditionChanged(Condition exitCondition) {
setExitCondition(exitCondition);
if (DEBUG) Log.d(mTag, "handleExitConditionChanged " + mExitCondition);
+ if (exitCondition == null) return;
final int N = getVisibleConditions();
for (int i = 0; i < N; i++) {
final ConditionTag tag = getConditionTagAt(i);
- if (tag != null) {
- if (sameConditionId(tag.condition, mExitCondition)) {
- bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
- }
+ if (tag != null && sameConditionId(tag.condition, mExitCondition)) {
+ bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
+ return;
}
}
+ if (mCountdownConditionSupported && ZenModeConfig.isValidCountdownConditionId(
+ exitCondition.id)) {
+ bind(exitCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
+ COUNTDOWN_CONDITION_INDEX);
+ }
}
private Condition getSelectedCondition() {
@@ -519,7 +600,7 @@
}
}
// ensure something is selected
- if (mExpanded && isShown()) {
+ if (mExpanded) {
ensureSelection();
}
mZenConditions.setVisibility(mSessionZen != Global.ZEN_MODE_OFF ? View.VISIBLE : View.GONE);
@@ -597,7 +678,9 @@
if (foreverTag == null) return;
if (DEBUG) Log.d(mTag, "Selecting a default");
final int favoriteIndex = mPrefs.getMinuteIndex();
- if (favoriteIndex == -1 || !mCountdownConditionSupported) {
+ if (mExitCondition != null && mExitCondition.equals(mTimeCondition)) {
+ getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
+ } else if (favoriteIndex == -1 || !mCountdownConditionSupported) {
foreverTag.rb.setChecked(true);
} else {
mTimeCondition = ZenModeConfig.toTimeCondition(mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index efb9fea4..9249df6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -14,6 +14,8 @@
package com.android.systemui.statusbar;
+import static junit.framework.Assert.assertTrue;
+
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -49,6 +51,8 @@
public void testRecreateMenu() {
NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
row.createMenu(null);
+ assertTrue(row.getMenuView() != null);
row.createMenu(null);
+ assertTrue(row.getMenuView() != null);
}
}
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index c4a2831..65cc17e 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -173,6 +173,9 @@
// Package: android
NOTE_ACCOUNT_CREDENTIAL_PERMISSION = 38;
+ // Inform the user their phone recently shut down due to high temperature
+ NOTE_THERMAL_SHUTDOWN = 39;
+
// ADD_NEW_IDS_ABOVE_THIS_LINE
// Legacy IDs with arbitrary values appear below
// Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index cb6d4df3..0003941 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1586,7 +1586,7 @@
private void showAccessibilityButtonTargetSelection() {
Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- mContext.startActivity(intent);
+ mContext.startActivityAsUser(intent, UserHandle.of(mCurrentUserId));
}
private void scheduleNotifyClientsOfServicesStateChange(UserState userState) {
@@ -2036,10 +2036,16 @@
}
if (!shortcutServiceIsInstalled) {
userState.mServiceToEnableWithShortcut = null;
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null, userState.mUserId);
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0, userState.mUserId);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null, userState.mUserId);
+
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0, userState.mUserId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 64dee58..0f18c87 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -28,7 +28,6 @@
import android.service.autofill.FillResponse;
import android.service.autofill.SaveInfo;
import android.text.TextUtils;
-import android.text.format.DateUtils;
import android.util.Slog;
import android.view.autofill.AutofillId;
import android.view.autofill.IAutofillWindowPresenter;
@@ -50,8 +49,6 @@
public final class AutoFillUI {
private static final String TAG = "AutoFillUI";
- private static final int MAX_SAVE_TIMEOUT_MS = (int) (30 * DateUtils.SECOND_IN_MILLIS);
-
private final Handler mHandler = UiThread.getHandler();
private final @NonNull Context mContext;
@@ -60,7 +57,6 @@
private @Nullable AutoFillUiCallback mCallback;
- private int mSaveTimeoutMs = (int) (5 * DateUtils.SECOND_IN_MILLIS);
private final MetricsLogger mMetricsLogger = new MetricsLogger();
public interface AutoFillUiCallback {
@@ -273,22 +269,11 @@
mHandler.post(this::hideAllUiThread);
}
- public void setSaveTimeout(int timeout) {
- if (timeout > MAX_SAVE_TIMEOUT_MS) {
- throw new IllegalArgumentException("Maximum value is " + MAX_SAVE_TIMEOUT_MS + "ms");
- }
- if (timeout <= 0) {
- throw new IllegalArgumentException("Must be a positive value");
- }
- mSaveTimeoutMs = timeout;
- }
-
public void dump(PrintWriter pw) {
pw.println("Autofill UI");
final String prefix = " ";
final String prefix2 = " ";
pw.print(prefix); pw.print("showsSaveUi: "); pw.println(mSaveUi != null);
- pw.print(prefix); pw.print("save timeout: "); pw.println(mSaveTimeoutMs);
if (mFillUi != null) {
pw.print(prefix); pw.println("showsFillUi: true");
mFillUi.dump(pw, prefix2);
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index b69d1dc..a89df92 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -69,7 +69,6 @@
private final @Nullable ArrayAdapter<ViewItem> mAdapter;
private @Nullable String mFilterText;
- private final String mAccessibilityTitle;
private int mContentWidth;
private int mContentHeight;
@@ -81,7 +80,9 @@
@NonNull Callback callback) {
mCallback = callback;
- mAccessibilityTitle = context.getString(R.string.autofill_picker_accessibility_title);
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ final ViewGroup decor = (ViewGroup) inflater.inflate(
+ R.layout.autofill_dataset_picker, null);
if (response.getAuthentication() != null) {
mListView = null;
@@ -89,23 +90,23 @@
final View content;
try {
- content = response.getPresentation().apply(context, null);
+ content = response.getPresentation().apply(context, decor);
+ decor.addView(content);
} catch (RuntimeException e) {
callback.onCanceled();
Slog.e(TAG, "Error inflating remote views", e);
mWindow = null;
return;
}
- final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
- final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
+ final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
content.measure(widthMeasureSpec, heightMeasureSpec);
content.setOnClickListener(v -> mCallback.onResponsePicked(response));
- content.setElevation(context.getResources().getDimension(R.dimen.floating_window_z));
// TODO(b/33197203 , b/36660292): temporary limiting maximum height and minimum width
mContentWidth = Math.max(content.getMeasuredWidth(), 1000);
mContentHeight = Math.min(content.getMeasuredHeight(), 500);
- mWindow = new AnchoredWindow(content);
+ mWindow = new AnchoredWindow(decor);
mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
} else {
final int datasetCount = response.getDatasets().size();
@@ -139,9 +140,9 @@
}
};
- final LayoutInflater inflater = LayoutInflater.from(context);
- mListView = (ListView) inflater.inflate(R.layout.autofill_dataset_picker, null);
+ mListView = decor.findViewById(R.id.autofill_dataset_list);
mListView.setAdapter(mAdapter);
+ mListView.setVisibility(View.VISIBLE);
mListView.setOnItemClickListener((adapter, view, position, id) -> {
final ViewItem vi = mAdapter.getItem(position);
mCallback.onDatasetPicked(vi.getDataset());
@@ -154,11 +155,12 @@
}
applyNewFilterText();
- mWindow = new AnchoredWindow(mListView);
+ mWindow = new AnchoredWindow(decor);
}
}
private void applyNewFilterText() {
+ final int oldCount = mAdapter.getCount();
mAdapter.getFilter().filter(mFilterText, (count) -> {
if (mDestroyed) {
return;
@@ -175,6 +177,9 @@
} else {
mListView.setVerticalScrollBarEnabled(false);
}
+ if (mAdapter.getCount() != oldCount) {
+ mListView.requestLayout();
+ }
}
});
}
@@ -312,7 +317,8 @@
public void show(WindowManager.LayoutParams params) {
try {
if (!mShowing) {
- params.accessibilityTitle = mAccessibilityTitle;
+ params.accessibilityTitle = mContentView.getContext()
+ .getString(R.string.autofill_picker_accessibility_title);
mWm.addView(mContentView, params);
mContentView.setOnTouchListener(this);
mShowing = true;
@@ -352,7 +358,6 @@
pw.print(prefix); pw.print("mListView: "); pw.println(mListView);
pw.print(prefix); pw.print("mAdapter: "); pw.println(mAdapter != null);
pw.print(prefix); pw.print("mFilterText: "); pw.println(mFilterText);
- pw.print(prefix); pw.print("mAccessibilityTitle: "); pw.println(mAccessibilityTitle);
pw.print(prefix); pw.print("mContentWidth: "); pw.println(mContentWidth);
pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index dcf6fd7..1a5ec61 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -416,6 +416,29 @@
return resOps;
}
+ private ArrayList<AppOpsManager.OpEntry> collectOps(SparseIntArray uidOps, int[] ops) {
+ ArrayList<AppOpsManager.OpEntry> resOps = null;
+ if (ops == null) {
+ resOps = new ArrayList<>();
+ for (int j=0; j<uidOps.size(); j++) {
+ resOps.add(new AppOpsManager.OpEntry(uidOps.keyAt(j), uidOps.valueAt(j),
+ 0, 0, 0, -1, null));
+ }
+ } else {
+ for (int j=0; j<ops.length; j++) {
+ int index = uidOps.indexOfKey(ops[j]);
+ if (index >= 0) {
+ if (resOps == null) {
+ resOps = new ArrayList<>();
+ }
+ resOps.add(new AppOpsManager.OpEntry(uidOps.keyAt(index), uidOps.valueAt(index),
+ 0, 0, 0, -1, null));
+ }
+ }
+ }
+ return resOps;
+ }
+
@Override
public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
@@ -473,6 +496,27 @@
}
}
+ @Override
+ public List<AppOpsManager.PackageOps> getUidOps(int uid, int[] ops) {
+ mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
+ Binder.getCallingPid(), Binder.getCallingUid(), null);
+ synchronized (this) {
+ UidState uidState = getUidStateLocked(uid, false);
+ if (uidState == null) {
+ return null;
+ }
+ ArrayList<AppOpsManager.OpEntry> resOps = collectOps(uidState.opModes, ops);
+ if (resOps == null) {
+ return null;
+ }
+ ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>();
+ AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
+ null, uidState.uid, resOps);
+ res.add(resPackage);
+ return res;
+ }
+ }
+
private void pruneOp(Op op, int uid, String packageName) {
if (op.time == 0 && op.rejectTime == 0) {
Ops ops = getOpsRawLocked(uid, packageName, false);
@@ -1669,6 +1713,7 @@
int op;
int mode;
int packageUid;
+ int nonpackageUid;
Shell(IAppOpsService iface, AppOpsService internal) {
mInterface = iface;
@@ -1790,15 +1835,59 @@
if (userId == UserHandle.USER_CURRENT) {
userId = ActivityManager.getCurrentUser();
}
- if ("root".equals(packageName)) {
- packageUid = 0;
- } else {
- packageUid = AppGlobals.getPackageManager().getPackageUid(packageName,
- PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+ nonpackageUid = -1;
+ try {
+ nonpackageUid = Integer.parseInt(packageName);
+ } catch (NumberFormatException e) {
}
- if (packageUid < 0) {
- err.println("Error: No UID for " + packageName + " in user " + userId);
- return -1;
+ if (nonpackageUid == -1 && packageName.length() > 1 && packageName.charAt(0) == 'u'
+ && packageName.indexOf('.') < 0) {
+ int i = 1;
+ while (i < packageName.length() && packageName.charAt(i) >= '0'
+ && packageName.charAt(i) <= '9') {
+ i++;
+ }
+ if (i > 1 && i < packageName.length()) {
+ String userStr = packageName.substring(1, i);
+ try {
+ int user = Integer.parseInt(userStr);
+ char type = packageName.charAt(i);
+ i++;
+ int startTypeVal = i;
+ while (i < packageName.length() && packageName.charAt(i) >= '0'
+ && packageName.charAt(i) <= '9') {
+ i++;
+ }
+ if (i > startTypeVal) {
+ String typeValStr = packageName.substring(startTypeVal, i);
+ try {
+ int typeVal = Integer.parseInt(typeValStr);
+ if (type == 'a') {
+ nonpackageUid = UserHandle.getUid(user,
+ typeVal + Process.FIRST_APPLICATION_UID);
+ } else if (type == 's') {
+ nonpackageUid = UserHandle.getUid(user, typeVal);
+ }
+ } catch (NumberFormatException e) {
+ }
+ }
+ } catch (NumberFormatException e) {
+ }
+ }
+ }
+ if (nonpackageUid != -1) {
+ packageName = null;
+ } else {
+ if ("root".equals(packageName)) {
+ packageUid = 0;
+ } else {
+ packageUid = AppGlobals.getPackageManager().getPackageUid(packageName,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+ }
+ if (packageUid < 0) {
+ err.println("Error: No UID for " + packageName + " in user " + userId);
+ return -1;
+ }
}
return 0;
}
@@ -1814,9 +1903,9 @@
pw.println("AppOps service (appops) commands:");
pw.println(" help");
pw.println(" Print this help text.");
- pw.println(" set [--user <USER_ID>] <PACKAGE> <OP> <MODE>");
+ pw.println(" set [--user <USER_ID>] <PACKAGE | UID> <OP> <MODE>");
pw.println(" Set the mode for a particular application and operation.");
- pw.println(" get [--user <USER_ID>] <PACKAGE> [<OP>]");
+ pw.println(" get [--user <USER_ID>] <PACKAGE | UID> [<OP>]");
pw.println(" Return the mode for a particular application and optional operation.");
pw.println(" query-op [--user <USER_ID>] <OP> [<MODE>]");
pw.println(" Print all packages that currently have the given op in the given mode.");
@@ -1858,7 +1947,12 @@
return -1;
}
- shell.mInterface.setMode(shell.op, shell.packageUid, shell.packageName, mode);
+ if (shell.packageName != null) {
+ shell.mInterface.setMode(shell.op, shell.packageUid, shell.packageName,
+ mode);
+ } else {
+ shell.mInterface.setUidMode(shell.op, shell.nonpackageUid, mode);
+ }
return 0;
}
case "get": {
@@ -1867,9 +1961,16 @@
return res;
}
- List<AppOpsManager.PackageOps> ops = shell.mInterface.getOpsForPackage(
- shell.packageUid, shell.packageName,
- shell.op != AppOpsManager.OP_NONE ? new int[] {shell.op} : null);
+ List<AppOpsManager.PackageOps> ops;
+ if (shell.packageName != null) {
+ ops = shell.mInterface.getOpsForPackage(
+ shell.packageUid, shell.packageName,
+ shell.op != AppOpsManager.OP_NONE ? new int[]{shell.op} : null);
+ } else {
+ ops = shell.mInterface.getUidOps(
+ shell.nonpackageUid,
+ shell.op != AppOpsManager.OP_NONE ? new int[]{shell.op} : null);
+ }
if (ops == null || ops.size() <= 0) {
pw.println("No operations.");
return 0;
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index f0720f3..9e054c3 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -146,6 +146,9 @@
// The maximum interval a location request can have and still be considered "high power".
private static final long HIGH_POWER_INTERVAL_MS = 5 * 60 * 1000;
+ private static final int FOREGROUND_IMPORTANCE_CUTOFF
+ = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+
// default background throttling interval if not overriden in settings
private static final long DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS = 30 * 60 * 1000;
@@ -375,7 +378,7 @@
}
};
mActivityManager.addOnUidImportanceListener(uidImportanceListener,
- ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE);
+ FOREGROUND_IMPORTANCE_CUTOFF);
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
updateUserProfiles(mCurrentUserId);
@@ -452,7 +455,7 @@
}
private static boolean isImportanceForeground(int importance) {
- return importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+ return importance <= FOREGROUND_IMPORTANCE_CUTOFF;
}
/**
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 7dd75df..c77820b 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -324,7 +324,7 @@
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
- + " (pid=" + Binder.getCallingPid()
+ + " (pid=" + callingPid
+ ") when starting service " + service);
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
@@ -353,29 +353,24 @@
// If this isn't a direct-to-foreground start, check our ability to kick off an
// arbitrary service
if (!r.startRequested && !fgRequired) {
- final long token = Binder.clearCallingIdentity();
- try {
- // Before going further -- if this app is not allowed to start services in the
- // background, then at this point we aren't going to let it period.
- final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
- r.appInfo.targetSdkVersion, callingPid, false, false);
- if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
- Slog.w(TAG, "Background start not allowed: service "
- + service + " to " + r.name.flattenToShortString()
- + " from pid=" + callingPid + " uid=" + callingUid
- + " pkg=" + callingPackage);
- if (allowed == ActivityManager.APP_START_MODE_DELAYED) {
- // In this case we are silently disabling the app, to disrupt as
- // little as possible existing apps.
- return null;
- }
- // This app knows it is in the new model where this operation is not
- // allowed, so tell it what has happened.
- UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
- return new ComponentName("?", "app is in background uid " + uidRec);
+ // Before going further -- if this app is not allowed to start services in the
+ // background, then at this point we aren't going to let it period.
+ final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
+ r.appInfo.targetSdkVersion, callingPid, false, false);
+ if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
+ Slog.w(TAG, "Background start not allowed: service "
+ + service + " to " + r.name.flattenToShortString()
+ + " from pid=" + callingPid + " uid=" + callingUid
+ + " pkg=" + callingPackage);
+ if (allowed == ActivityManager.APP_START_MODE_DELAYED) {
+ // In this case we are silently disabling the app, to disrupt as
+ // little as possible existing apps.
+ return null;
}
- } finally {
- Binder.restoreCallingIdentity(token);
+ // This app knows it is in the new model where this operation is not
+ // allowed, so tell it what has happened.
+ UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
+ return new ComponentName("?", "app is in background uid " + uidRec);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 35654d7..74a54f5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3878,7 +3878,8 @@
// the per-user SELinux context must be set
if (TextUtils.isEmpty(app.info.seInfoUser)) {
Slog.wtf(TAG, "SELinux tag not defined",
- new IllegalStateException("SELinux tag not defined"));
+ new IllegalStateException("SELinux tag not defined for "
+ + app.info.packageName + " (uid " + app.uid + ")"));
}
final String seInfo = app.info.seInfo
+ (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
@@ -5243,10 +5244,10 @@
}
private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
- IBinder threadBinder = thread.asBinder();
+ final IBinder threadBinder = thread.asBinder();
// Find the application record.
for (int i=mLruProcesses.size()-1; i>=0; i--) {
- ProcessRecord rec = mLruProcesses.get(i);
+ final ProcessRecord rec = mLruProcesses.get(i);
if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
return i;
}
@@ -5261,7 +5262,27 @@
}
int appIndex = getLRURecordIndexForAppLocked(thread);
- return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
+ if (appIndex >= 0) {
+ return mLruProcesses.get(appIndex);
+ }
+
+ // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
+ // double-check that.
+ final IBinder threadBinder = thread.asBinder();
+ final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
+ for (int i = pmap.size()-1; i >= 0; i--) {
+ final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
+ for (int j = procs.size()-1; j >= 0; j--) {
+ final ProcessRecord proc = procs.valueAt(j);
+ if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
+ Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
+ + proc);
+ return proc;
+ }
+ }
+ }
+
+ return null;
}
final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
@@ -7803,7 +7824,7 @@
// Activity supports picture-in-picture, now check that we can enter PiP at this
// point, if it is
if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
- false /* noThrow */)) {
+ false /* noThrow */, false /* beforeStopping */)) {
return false;
}
@@ -13025,6 +13046,19 @@
}
@Override
+ public int getUidProcessState(int uid, String callingPackage) {
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "getUidProcessState");
+ }
+
+ synchronized (this) {
+ UidRecord uidRec = mActiveUids.get(uid);
+ return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
+ }
+ }
+
+ @Override
public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
String callingPackage) {
if (!hasUsageStatsPermission(callingPackage)) {
@@ -17861,10 +17895,14 @@
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
- ComponentName res = mServices.startServiceLocked(caller, service,
- resolvedType, id, notification, callingPid, callingUid,
- requireForeground, callingPackage, userId);
- Binder.restoreCallingIdentity(origId);
+ ComponentName res;
+ try {
+ res = mServices.startServiceLocked(caller, service,
+ resolvedType, id, notification, callingPid, callingUid,
+ requireForeground, callingPackage, userId);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
return res;
}
}
@@ -17876,9 +17914,13 @@
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startServiceInPackage: " + service + " type=" + resolvedType);
final long origId = Binder.clearCallingIdentity();
- ComponentName res = mServices.startServiceLocked(null, service,
- resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
- Binder.restoreCallingIdentity(origId);
+ ComponentName res;
+ try {
+ res = mServices.startServiceLocked(null, service,
+ resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
return res;
}
}
@@ -23761,24 +23803,6 @@
}
@Override
- public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
- final int userId = intent.getCreatorUserHandle().getIdentifier();
- if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
- return false;
- }
- IIntentSender target = intent.getTarget();
- if (!(target instanceof PendingIntentRecord)) {
- return false;
- }
- final PendingIntentRecord record = (PendingIntentRecord) target;
- final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
- record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
- // For direct boot aware activities, they can be shown without triggering a work challenge
- // before the profile user is unlocked.
- return rInfo != null && rInfo.activityInfo != null;
- }
-
- @Override
public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
throws RemoteException {
final long callingId = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 04c2af5..0fcf3e6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2498,6 +2498,10 @@
pw.println(" Start a Service. Options are:");
pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
pw.println(" specified then run as the current user.");
+ pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
+ pw.println(" Start a foreground Service. Options are:");
+ pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
+ pw.println(" specified then run as the current user.");
pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
pw.println(" Stop a Service. Options are:");
pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 95d7158..276b267 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -423,11 +423,11 @@
pw.print("\"");
pw.print(" primaryColor=");
pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
- pw.print(" backgroundColor=");
+ pw.print(prefix + " backgroundColor=");
pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
- pw.print(" statusBarColor=");
+ pw.print(prefix + " statusBarColor=");
pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
- pw.print(" navigationBarColor=");
+ pw.print(prefix + " navigationBarColor=");
pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
}
if (iconFilename == null && taskDescription.getIcon() != null) {
@@ -1163,10 +1163,13 @@
}
/**
+ * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
+ * the activity has requested to enter PiP when it would otherwise be stopped.
+ *
* @return whether this activity is currently allowed to enter PIP, throwing an exception if
* the activity is not currently visible and {@param noThrow} is not set.
*/
- boolean checkEnterPictureInPictureState(String caller, boolean noThrow) {
+ boolean checkEnterPictureInPictureState(String caller, boolean noThrow, boolean beforeStopping) {
// Check app-ops and see if PiP is supported for this package
if (!checkEnterPictureInPictureAppOpsState()) {
return false;
@@ -1177,17 +1180,24 @@
return false;
}
- boolean isCurrentAppLocked = mStackSupervisor.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
boolean isKeyguardLocked = service.isKeyguardLocked();
+ boolean isCurrentAppLocked = mStackSupervisor.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
boolean hasPinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID) != null;
// Don't return early if !isNotLocked, since we want to throw an exception if the activity
// is in an incorrect state
boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
+
+ // We don't allow auto-PiP when something else is already pipped.
+ if (beforeStopping && hasPinnedStack) {
+ return false;
+ }
+
switch (state) {
case RESUMED:
// When visible, allow entering PiP if the app is not locked. If it is over the
// keyguard, then we will prompt to unlock in the caller before entering PiP.
- return !isCurrentAppLocked;
+ return !isCurrentAppLocked &&
+ (supportsPictureInPictureWhilePausing || !beforeStopping);
case PAUSING:
case PAUSED:
// When pausing, then only allow enter PiP as in the resume state, and in addition,
@@ -1561,8 +1571,8 @@
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
}
- void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
- mWindowContainerController.notifyAppResumed(wasStopped, allowSavedSurface);
+ void notifyAppResumed(boolean wasStopped) {
+ mWindowContainerController.notifyAppResumed(wasStopped);
}
void notifyUnknownVisibilityLaunched() {
@@ -2112,7 +2122,8 @@
service.compatibilityInfoForPackageLocked(info.applicationInfo);
final boolean shown = mWindowContainerController.addStartingWindow(packageName, theme,
compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
- prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning());
+ prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
+ allowTaskSnapshot());
if (shown) {
mStartingWindowState = STARTING_WINDOW_SHOWN;
}
@@ -2552,7 +2563,7 @@
preserveWindowOnDeferredRelaunch = false;
}
- boolean isProcessRunning() {
+ private boolean isProcessRunning() {
ProcessRecord proc = app;
if (proc == null) {
proc = service.mProcessNames.get(processName, info.applicationInfo.uid);
@@ -2560,6 +2571,26 @@
return proc != null && proc.thread != null;
}
+ /**
+ * @return Whether a task snapshot starting window may be shown.
+ */
+ private boolean allowTaskSnapshot() {
+ if (newIntents == null) {
+ return true;
+ }
+
+ // Restrict task snapshot starting window to launcher start, or there is no intent at all
+ // (eg. task being brought to front). If the intent is something else, likely the app is
+ // going to show some specific page or view, instead of what's left last time.
+ for (int i = newIntents.size() - 1; i >= 0; i--) {
+ final Intent intent = newIntents.get(i);
+ if (intent != null && !ActivityRecord.isMainIntent(intent)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
out.attribute(null, ATTR_ID, String.valueOf(createTime));
out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index f551a44..b998314 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -65,7 +65,6 @@
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
@@ -1167,8 +1166,6 @@
final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
- // TODO(b/37244415): This just wrong. We should also be moving PAUSED activities to
- // the stopped state when we are sleeping.
if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED
|| r.state == ActivityState.PAUSED || r.state == ActivityState.PAUSING) {
r.setSleeping(true);
@@ -1803,15 +1800,6 @@
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Skipping: already visible at " + r);
- if (r.state == STOPPED) {
- // In this case the activity is visible, but in the stopped state.
- // This sometimes happens if the activity is behind the lockscreen.
- // Restart the activity to the paused or resumed state since we want
- // it to be in the visible state now.
- makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
- resumeNextActivity, r);
- }
-
if (r.handleAlreadyVisible()) {
resumeNextActivity = false;
}
@@ -2001,10 +1989,10 @@
// keeping the screen frozen.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.state);
try {
- r.setVisible(false);
switch (r.state) {
case STOPPING:
case STOPPED:
+ r.setVisible(false);
if (r.app != null && r.app.thread != null) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Scheduling invisibility: " + r);
@@ -2023,6 +2011,7 @@
// This case created for transitioning activities from
// translucent to opaque {@link Activity#convertToOpaque}.
if (visibleBehind == r) {
+ r.setVisible(false);
releaseBackgroundResources(r);
} else {
// If this activity is in a state where it can currently enter
@@ -2030,7 +2019,18 @@
// the activity tries to enterPictureInPictureMode() later. Otherwise,
// we will try and stop the activity next time idle is processed.
final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
- "makeInvisible", true /* noThrow */);
+ "makeInvisible", true /* noThrow */, true /* beforeStopping */);
+
+ if (canEnterPictureInPicture) {
+ // We set r.visible=false so that Stop will later
+ // call setVisible for us. In this case
+ // we don't want to call setVisible(false) to avoid
+ // notifying the client of this intermittent invisible
+ // state.
+ r.visible = false;
+ } else {
+ r.setVisible(false);
+ }
addToStopping(r, true /* scheduleIdle */,
canEnterPictureInPicture /* idleDelayed */);
}
@@ -2531,26 +2531,14 @@
}
}
- boolean allowSavedSurface = true;
if (next.newIntents != null) {
- // Restrict saved surface to launcher start, or there is no intent at all
- // (eg. task being brought to front). If the intent is something else,
- // likely the app is going to show some specific page or view, instead of
- // what's left last time.
- for (int i = next.newIntents.size() - 1; i >= 0; i--) {
- final Intent intent = next.newIntents.get(i);
- if (intent != null && !ActivityRecord.isMainIntent(intent)) {
- allowSavedSurface = false;
- break;
- }
- }
next.app.thread.scheduleNewIntent(
next.newIntents, next.appToken, false /* andPause */);
}
// Well the app will no longer be stopped.
// Clear app token stopped state in window manager if needed.
- next.notifyAppResumed(next.stopped, allowSavedSurface);
+ next.notifyAppResumed(next.stopped);
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
System.identityHashCode(next), next.getTask().taskId,
@@ -3985,6 +3973,19 @@
task.isOverHomeStack()) {
mStackSupervisor.moveHomeStackTaskToTop(reason);
}
+
+ if (onlyHasTaskOverlays) {
+ // When destroying a task, tell the supervisor to remove it so that any activity it
+ // has can be cleaned up correctly. This is currently the only place where we remove
+ // a task with the DESTROYING mode, so instead of passing the onlyHasTaskOverlays
+ // state into removeTask(), we just clear the task here before the other residual
+ // work.
+ // TODO: If the callers to removeTask() changes such that we have multiple places
+ // where we are destroying the task, move this back into removeTask()
+ mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */,
+ !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY);
+ task.removeWindowContainer();
+ }
removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING);
}
cleanUpActivityServicesLocked(r);
@@ -5044,14 +5045,6 @@
* {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}.
*/
void removeTask(TaskRecord task, String reason, int mode) {
- if (mode == REMOVE_TASK_MODE_DESTROYING) {
- // When destroying a task, tell the supervisor to remove it so that any activity it has
- // can be cleaned up correctly
- mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */,
- !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY);
- task.removeWindowContainer();
- }
-
for (ActivityRecord record : task.mActivities) {
onActivityRemovedFromStack(record);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 88de8a5..68e25c3 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1477,12 +1477,11 @@
stack.minimalResumeActivityLocked(r);
} else {
// This activity is not starting in the resumed state... which should look like we asked
- // it to resume+pause (but remain visible), and it has done so and reported back the
+ // it to pause+stop (but remain visible), and it has done so and reported back the
// current icicle and other state.
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to PAUSED: " + r + " (starting in paused state)");
r.state = PAUSED;
- r.stopped = false;
}
// Launch the new version setup screen if needed. We do this -after-
@@ -3090,7 +3089,6 @@
}
}
mGoingToSleepActivities.clear();
- ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
void activitySleptLocked(ActivityRecord r) {
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index cafc4f0..b91c7b1 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -210,11 +210,7 @@
if (!mService.mUserController.shouldConfirmCredentials(userId)) {
return null;
}
- // Allow direct boot aware activity to be displayed before the user is unlocked.
- if (aInfo.directBootAware && mService.mUserController.isUserRunningLocked(userId,
- ActivityManager.FLAG_AND_LOCKED)) {
- return null;
- }
+ // TODO(b/28935539): should allow certain activities to bypass work challenge
final IIntentSender target = mService.getIntentSenderLocked(
INTENT_SENDER_ACTIVITY, callingPackage,
Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent },
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index dd3d4e0..baa71d7 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -16,6 +16,8 @@
package com.android.server.am;
+import android.content.pm.IPackageManager;
+import android.content.pm.PermissionInfo;
import android.os.Trace;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -795,6 +797,31 @@
.sendToTarget();
}
+ /**
+ * Return true if all given permissions are signature-only perms.
+ */
+ final boolean isSignaturePerm(String[] perms) {
+ if (perms == null) {
+ return false;
+ }
+ IPackageManager pm = AppGlobals.getPackageManager();
+ for (int i = perms.length-1; i >= 0; i--) {
+ try {
+ PermissionInfo pi = pm.getPermissionInfo(perms[i], 0);
+ if ((pi.protectionLevel & (PermissionInfo.PROTECTION_MASK_BASE
+ | PermissionInfo.PROTECTION_FLAG_PRIVILEGED))
+ != PermissionInfo.PROTECTION_SIGNATURE) {
+ // If this a signature permission and NOT allowed for privileged apps, it
+ // is okay... otherwise, nope!
+ return false;
+ }
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+ return true;
+ }
+
final void processNextBroadcast(boolean fromMsg) {
synchronized(mService) {
BroadcastRecord r;
@@ -1246,7 +1273,8 @@
|| (r.intent.getComponent() == null
&& r.intent.getPackage() == null
&& ((r.intent.getFlags()
- & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0))) {
+ & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
+ && !isSignaturePerm(r.requiredPermissions))) {
mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
component.getPackageName());
Slog.w(TAG, "Background execution not allowed: receiving "
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 51aa4f8..9eda929 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -57,7 +57,7 @@
.setCurve(new float[] { 0.f, 1.f } /* times */,
new float[] { 1.f, 0.2f } /* volumes */)
.setOptionFlags(VolumeShaper.Configuration.OPTION_FLAG_CLOCK_TIME)
- .setDurationMs(MediaFocusControl.getFocusRampTimeMs(
+ .setDurationMillis(MediaFocusControl.getFocusRampTimeMs(
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()))
diff --git a/services/core/java/com/android/server/fingerprint/EnumerateClient.java b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
index 34f245f..1b8b89c 100644
--- a/services/core/java/com/android/server/fingerprint/EnumerateClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
@@ -58,7 +58,7 @@
public int stop(boolean initiatedByClient) {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
- Slog.w(TAG, "stopAuthentication: no fingerprint HAL!");
+ Slog.w(TAG, "stopEnumeration: no fingerprint HAL!");
return ERROR_ESRCH;
}
try {
@@ -102,12 +102,12 @@
@Override
public boolean onEnrollResult(int fingerId, int groupId, int rem) {
if (DEBUG) Slog.w(TAG, "onEnrollResult() called for enumerate!");
- return true; // Invalid for Remove
+ return true; // Invalid for Enumerate.
}
@Override
public boolean onRemoved(int fingerId, int groupId, int remaining) {
if (DEBUG) Slog.w(TAG, "onRemoved() called for enumerate!");
- return true; // Invalid for Authenticate
+ return true; // Invalid for Enumerate.
}
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 85f7056..9b984c1 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -85,6 +85,7 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.LinkedList;
/**
* A service to manage multiple clients that want to access the fingerprint HAL API.
@@ -96,6 +97,7 @@
public class FingerprintService extends SystemService implements IHwBinder.DeathRecipient {
static final String TAG = "FingerprintService";
static final boolean DEBUG = true;
+ private static final boolean CLEANUP_UNUSED_FP = false;
private static final String FP_DATA_DIR = "fpdata";
private static final int MSG_USER_SWITCHING = 10;
private static final String ACTION_LOCKOUT_RESET =
@@ -134,6 +136,20 @@
private ClientMonitor mPendingClient;
private PerformanceStats mPerformanceStats;
+
+ private IBinder mToken = new Binder(); // used for internal FingerprintService enumeration
+ private LinkedList<Integer> mEnumeratingUserIds = new LinkedList<>();
+ private ArrayList<UserFingerprint> mUnknownFingerprints = new ArrayList<>(); // hw finterprints
+
+ private class UserFingerprint {
+ Fingerprint f;
+ int userId;
+ public UserFingerprint(Fingerprint f, int userId) {
+ this.f = f;
+ this.userId = userId;
+ }
+ }
+
// Normal fingerprint authentications are tracked by mPerformanceMap.
private HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>();
@@ -185,6 +201,7 @@
+ (mCurrentClient != null ? mCurrentClient.getOwnerString() : "null")
+ " failed to respond to cancel, starting client "
+ (mPendingClient != null ? mPendingClient.getOwnerString() : "null"));
+
mCurrentClient = null;
startClient(mPendingClient, false);
}
@@ -239,6 +256,7 @@
if (mHalDeviceId != 0) {
loadAuthenticatorIds();
updateActiveGroup(ActivityManager.getCurrentUser(), null);
+ doFingerprintCleanup(ActivityManager.getCurrentUser());
} else {
Slog.w(TAG, "Failed to open Fingerprint HAL!");
MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1);
@@ -253,7 +271,6 @@
// This operation can be expensive, so keep track of the elapsed time. Might need to move to
// background if it takes too long.
long t = System.currentTimeMillis();
-
mAuthenticatorIds.clear();
for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) {
int userId = getUserOrWorkProfileId(null, user.id);
@@ -268,14 +285,88 @@
}
}
+ private void doFingerprintCleanup(int userId) {
+ if (CLEANUP_UNUSED_FP) {
+ resetEnumerateState();
+ mEnumeratingUserIds.push(userId);
+ enumerateNextUser();
+ }
+ }
+
+ private void resetEnumerateState() {
+ if (DEBUG) Slog.v(TAG, "Enumerate cleaning up");
+ mEnumeratingUserIds.clear();
+ mUnknownFingerprints.clear();
+ }
+
+ private void enumerateNextUser() {
+ int nextUser = mEnumeratingUserIds.getFirst();
+ updateActiveGroup(nextUser, null);
+ boolean restricted = !hasPermission(MANAGE_FINGERPRINT);
+
+ if (DEBUG) Slog.v(TAG, "Enumerating user id " + nextUser + " of "
+ + mEnumeratingUserIds.size() + " remaining users");
+
+ startEnumerate(mToken, nextUser, null, restricted, true /* internal */);
+ }
+
+ // Remove unknown fingerprints from hardware
+ private void cleanupUnknownFingerprints() {
+ if (!mUnknownFingerprints.isEmpty()) {
+ Slog.w(TAG, "unknown fingerprint size: " + mUnknownFingerprints.size());
+ UserFingerprint uf = mUnknownFingerprints.get(0);
+ mUnknownFingerprints.remove(uf);
+ boolean restricted = !hasPermission(MANAGE_FINGERPRINT);
+ updateActiveGroup(uf.userId, null);
+ startRemove(mToken, uf.f.getFingerId(), uf.f.getGroupId(), uf.userId, null,
+ restricted, true /* internal */);
+ } else {
+ resetEnumerateState();
+ }
+ }
+
protected void handleEnumerate(long deviceId, int fingerId, int groupId, int remaining) {
- if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId + ", gid="
- + groupId + "rem=" + remaining);
- // TODO: coordinate names with framework
+ if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId
+ + ", gid=" + groupId
+ + ", dev=" + deviceId
+ + ", rem=" + remaining);
+
+ ClientMonitor client = mCurrentClient;
+
+ if ( !(client instanceof InternalRemovalClient) && !(client instanceof EnumerateClient) ) {
+ return;
+ }
+ client.onEnumerationResult(fingerId, groupId, remaining);
+
+ // All fingerprints in hardware for this user were enumerated
+ if (remaining == 0) {
+ mEnumeratingUserIds.poll();
+
+ if (client instanceof InternalEnumerateClient) {
+ List<Fingerprint> enrolled = ((InternalEnumerateClient) client).getEnumeratedList();
+ Slog.w(TAG, "Added " + enrolled.size() + " enumerated fingerprints for deletion");
+ for (Fingerprint f : enrolled) {
+ mUnknownFingerprints.add(new UserFingerprint(f, client.getTargetUserId()));
+ }
+ }
+
+ removeClient(client);
+
+ if (!mEnumeratingUserIds.isEmpty()) {
+ enumerateNextUser();
+ } else if (client instanceof InternalEnumerateClient) {
+ if (DEBUG) Slog.v(TAG, "Finished enumerating all users");
+ // This will start a chain of InternalRemovalClients
+ cleanupUnknownFingerprints();
+ }
+ }
}
protected void handleError(long deviceId, int error, int vendorCode) {
ClientMonitor client = mCurrentClient;
+ if (client instanceof InternalRemovalClient || client instanceof InternalEnumerateClient) {
+ resetEnumerateState();
+ }
if (client != null && client.onError(error, vendorCode)) {
removeClient(client);
}
@@ -301,10 +392,20 @@
}
protected void handleRemoved(long deviceId, int fingerId, int groupId, int remaining) {
+ if (DEBUG) Slog.w(TAG, "Removed: fid=" + fingerId
+ + ", gid=" + groupId
+ + ", dev=" + deviceId
+ + ", rem=" + remaining);
+
ClientMonitor client = mCurrentClient;
if (client != null && client.onRemoved(fingerId, groupId, remaining)) {
removeClient(client);
}
+ if (client instanceof InternalRemovalClient && !mUnknownFingerprints.isEmpty()) {
+ cleanupUnknownFingerprints();
+ } else if (client instanceof InternalRemovalClient){
+ resetEnumerateState();
+ }
}
protected void handleAuthenticated(long deviceId, int fingerId, int groupId,
@@ -355,6 +456,7 @@
void handleUserSwitching(int userId) {
updateActiveGroup(userId, null);
+ doFingerprintCleanup(userId);
}
private void removeClient(ClientMonitor client) {
@@ -431,7 +533,15 @@
ClientMonitor currentClient = mCurrentClient;
if (currentClient != null) {
if (DEBUG) Slog.v(TAG, "request stop current client " + currentClient.getOwnerString());
- currentClient.stop(initiatedByClient);
+ if (currentClient instanceof InternalEnumerateClient ||
+ currentClient instanceof InternalRemovalClient) {
+ // This condition means we're currently running internal diagnostics to
+ // remove extra fingerprints in the hardware and/or the software
+ // TODO: design an escape hatch in case client never finishes
+ }
+ else {
+ currentClient.stop(initiatedByClient);
+ }
mPendingClient = newClient;
mHandler.removeCallbacks(mResetClientState);
mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
@@ -448,47 +558,86 @@
}
void startRemove(IBinder token, int fingerId, int groupId, int userId,
- IFingerprintServiceReceiver receiver, boolean restricted) {
+ IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "startRemove: no fingerprint HAL!");
return;
}
- RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token,
- receiver, fingerId, groupId, userId, restricted, token.toString()) {
- @Override
- public void notifyUserActivity() {
- FingerprintService.this.userActivity();
- }
- @Override
- public IBiometricsFingerprint getFingerprintDaemon() {
- return FingerprintService.this.getFingerprintDaemon();
- }
- };
- startClient(client, true);
+ if (internal) {
+ Context context = getContext();
+ InternalRemovalClient client = new InternalRemovalClient(context, mHalDeviceId,
+ token, receiver, fingerId, groupId, userId, restricted,
+ context.getOpPackageName()) {
+ @Override
+ public void notifyUserActivity() {
+
+ }
+ @Override
+ public IBiometricsFingerprint getFingerprintDaemon() {
+ return FingerprintService.this.getFingerprintDaemon();
+ }
+ };
+ startClient(client, true);
+ }
+ else {
+ RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token,
+ receiver, fingerId, groupId, userId, restricted, token.toString()) {
+ @Override
+ public void notifyUserActivity() {
+ FingerprintService.this.userActivity();
+ }
+
+ @Override
+ public IBiometricsFingerprint getFingerprintDaemon() {
+ return FingerprintService.this.getFingerprintDaemon();
+ }
+ };
+ startClient(client, true);
+ }
}
void startEnumerate(IBinder token, int userId,
- IFingerprintServiceReceiver receiver, boolean restricted) {
+ IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "startEnumerate: no fingerprint HAL!");
return;
}
- EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token,
- receiver, userId, userId, restricted, token.toString()) {
- @Override
- public void notifyUserActivity() {
- FingerprintService.this.userActivity();
- }
+ if (internal) {
+ List<Fingerprint> enrolledList = getEnrolledFingerprints(userId);
+ Context context = getContext();
+ InternalEnumerateClient client = new InternalEnumerateClient(context, mHalDeviceId,
+ token, receiver, userId, userId, restricted, context.getOpPackageName(),
+ enrolledList) {
+ @Override
+ public void notifyUserActivity() {
- @Override
- public IBiometricsFingerprint getFingerprintDaemon() {
- return FingerprintService.this.getFingerprintDaemon();
- }
- };
- startClient(client, true);
+ }
+
+ @Override
+ public IBiometricsFingerprint getFingerprintDaemon() {
+ return FingerprintService.this.getFingerprintDaemon();
+ }
+ };
+ startClient(client, true);
+ }
+ else {
+ EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token,
+ receiver, userId, userId, restricted, token.toString()) {
+ @Override
+ public void notifyUserActivity() {
+ FingerprintService.this.userActivity();
+ }
+
+ @Override
+ public IBiometricsFingerprint getFingerprintDaemon() {
+ return FingerprintService.this.getFingerprintDaemon();
+ }
+ };
+ startClient(client, true);
+ }
}
public List<Fingerprint> getEnrolledFingerprints(int userId) {
@@ -978,11 +1127,13 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- startRemove(token, fingerId, groupId, userId, receiver, restricted);
+ startRemove(token, fingerId, groupId, userId, receiver,
+ restricted, false /* internal */);
}
});
}
+ @Override // Binder call
public void enumerate(final IBinder token, final int userId,
final IFingerprintServiceReceiver receiver) {
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
@@ -990,7 +1141,7 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- startEnumerate(token, userId, receiver, restricted);
+ startEnumerate(token, userId, receiver, restricted, false /* internal */);
}
});
}
diff --git a/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java b/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java
new file mode 100644
index 0000000..f4d2596
--- /dev/null
+++ b/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.fingerprint;
+
+import android.content.Context;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.IFingerprintServiceReceiver;
+import android.os.IBinder;
+import android.util.Slog;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An internal class to help clean up unknown fingerprints in the hardware and software
+ */
+public abstract class InternalEnumerateClient extends EnumerateClient {
+
+ private List<Fingerprint> mEnrolledList;
+ private List<Fingerprint> mEnumeratedList = new ArrayList<>(); // list of fp to delete
+
+ public InternalEnumerateClient(Context context, long halDeviceId, IBinder token,
+ IFingerprintServiceReceiver receiver, int groupId, int userId,
+ boolean restricted, String owner, List<Fingerprint> enrolledList) {
+
+ super(context, halDeviceId, token, receiver, userId, groupId, restricted, owner);
+ mEnrolledList = enrolledList;
+ }
+
+ private void handleEnumeratedFingerprint(int fingerId, int groupId, int remaining) {
+
+ boolean matched = false;
+ for (int i=0; i<mEnrolledList.size(); i++) {
+ if (mEnrolledList.get(i).getFingerId() == fingerId) {
+ mEnrolledList.remove(i);
+ matched = true;
+ Slog.e(TAG, "Matched fingerprint fid=" + fingerId);
+ break;
+ }
+ }
+
+ // fingerId 0 means no fingerprints are in hardware
+ if (!matched && fingerId != 0) {
+ Fingerprint fingerprint = new Fingerprint("", groupId, fingerId, getHalDeviceId());
+ mEnumeratedList.add(fingerprint);
+ }
+ }
+
+ private void doFingerprintCleanup() {
+
+ if (mEnrolledList == null) {
+ return;
+ }
+
+ for (Fingerprint f : mEnrolledList) {
+ Slog.e(TAG, "Internal Enumerate: Removing dangling enrolled fingerprint: "
+ + f.getName() + " " + f.getFingerId() + " " + f.getGroupId()
+ + " " + f.getDeviceId());
+
+ FingerprintUtils.getInstance().removeFingerprintIdForUser(getContext(),
+ f.getFingerId(), getTargetUserId());
+ }
+ mEnrolledList.clear();
+ }
+
+ public List<Fingerprint> getEnumeratedList() {
+ return mEnumeratedList;
+ }
+
+ @Override
+ public boolean onEnumerationResult(int fingerId, int groupId, int remaining) {
+
+ handleEnumeratedFingerprint(fingerId, groupId, remaining);
+ if (remaining == 0) {
+ doFingerprintCleanup();
+ }
+
+ return fingerId == 0; // done when id hits 0
+ }
+
+}
diff --git a/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java b/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java
new file mode 100644
index 0000000..19f61fe
--- /dev/null
+++ b/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.fingerprint;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.hardware.fingerprint.IFingerprintServiceReceiver;
+import com.android.server.fingerprint.RemovalClient;
+
+public abstract class InternalRemovalClient extends RemovalClient {
+
+ public InternalRemovalClient(Context context, long halDeviceId, IBinder token,
+ IFingerprintServiceReceiver receiver, int fingerId, int groupId, int userId,
+ boolean restricted, String owner) {
+
+ super(context, halDeviceId, token, receiver, fingerId, groupId, userId, restricted, owner);
+
+ }
+}
diff --git a/services/core/java/com/android/server/fingerprint/RemovalClient.java b/services/core/java/com/android/server/fingerprint/RemovalClient.java
index ab1b9728..6610634 100644
--- a/services/core/java/com/android/server/fingerprint/RemovalClient.java
+++ b/services/core/java/com/android/server/fingerprint/RemovalClient.java
@@ -59,12 +59,23 @@
@Override
public int stop(boolean initiatedByClient) {
- // We don't actually stop remove, but inform the client that the cancel operation succeeded
- // so we can start the next operation.
- if (initiatedByClient) {
- onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, 0 /* vendorCode */);
+ IBiometricsFingerprint daemon = getFingerprintDaemon();
+ if (daemon == null) {
+ Slog.w(TAG, "stopRemoval: no fingerprint HAL!");
+ return ERROR_ESRCH;
}
- return 0;
+ try {
+ final int result = daemon.cancel();
+ if (result != 0) {
+ Slog.w(TAG, "stopRemoval failed, result=" + result);
+ return result;
+ }
+ if (DEBUG) Slog.w(TAG, "client " + getOwnerString() + " is no longer removing");
+ } catch (RemoteException e) {
+ Slog.e(TAG, "stopRemoval failed", e);
+ return ERROR_ESRCH;
+ }
+ return 0; // success
}
/*
diff --git a/services/core/java/com/android/server/job/JobCompletedListener.java b/services/core/java/com/android/server/job/JobCompletedListener.java
index 655abd7..34ba753b3 100644
--- a/services/core/java/com/android/server/job/JobCompletedListener.java
+++ b/services/core/java/com/android/server/job/JobCompletedListener.java
@@ -27,5 +27,5 @@
* Callback for when a job is completed.
* @param needsReschedule Whether the implementing class should reschedule this job.
*/
- void onJobCompleted(JobStatus jobStatus, boolean needsReschedule);
+ void onJobCompletedLocked(JobStatus jobStatus, boolean needsReschedule);
}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index cd3ba4c..a0d0d77 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -37,6 +37,7 @@
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.app.job.IJobScheduler;
+import android.app.job.JobWorkItem;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -582,20 +583,8 @@
mStartedUsers = ArrayUtils.removeInt(mStartedUsers, userHandle);
}
- /**
- * Entry point from client to schedule the provided job.
- * This cancels the job if it's already been scheduled, and replaces it with the one provided.
- * @param job JobInfo object containing execution parameters
- * @param uId The package identifier of the application this job is for.
- * @return Result of this operation. See <code>JobScheduler#RESULT_*</code> return codes.
- */
- public int schedule(JobInfo job, int uId) {
- return scheduleAsPackage(job, uId, null, -1, null);
- }
-
- public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId,
- String tag) {
- JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId, tag);
+ public int scheduleAsPackage(JobInfo job, JobWorkItem work, int uId, String packageName,
+ int userId, String tag) {
try {
if (ActivityManager.getService().isAppStartModeDisabled(uId,
job.getService().getPackageName())) {
@@ -605,9 +594,20 @@
}
} catch (RemoteException e) {
}
- if (DEBUG) Slog.d(TAG, "SCHEDULE: " + jobStatus.toShortString());
- JobStatus toCancel;
synchronized (mLock) {
+ final JobStatus toCancel = mJobs.getJobByUidAndJobId(uId, job.getId());
+
+ if (work != null && toCancel != null) {
+ // Fast path: we are adding work to an existing job, and the JobInfo is not
+ // changing. We can just directly enqueue this work in to the job.
+ if (toCancel.getJob().equals(job)) {
+ toCancel.enqueueWorkLocked(work);
+ return JobScheduler.RESULT_SUCCESS;
+ }
+ }
+
+ JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId, tag);
+ if (DEBUG) Slog.d(TAG, "SCHEDULE: " + jobStatus.toShortString());
// Jobs on behalf of others don't apply to the per-app job cap
if (ENFORCE_MAX_JOBS && packageName == null) {
if (mJobs.countJobsForUid(uId) > MAX_JOBS_PER_APP) {
@@ -618,15 +618,18 @@
}
// This may throw a SecurityException.
- jobStatus.prepare(ActivityManager.getService());
+ jobStatus.prepareLocked(ActivityManager.getService());
- toCancel = mJobs.getJobByUidAndJobId(uId, job.getId());
if (toCancel != null) {
cancelJobImpl(toCancel, jobStatus);
}
- startTrackingJob(jobStatus, toCancel);
+ if (work != null) {
+ // If work has been supplied, enqueue it into the new job.
+ jobStatus.enqueueWorkLocked(work);
+ }
+ startTrackingJobLocked(jobStatus, toCancel);
+ mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
}
- mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
return JobScheduler.RESULT_SUCCESS;
}
@@ -715,17 +718,17 @@
}
private void cancelJobImpl(JobStatus cancelled, JobStatus incomingJob) {
- if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
- cancelled.unprepare(ActivityManager.getService());
- stopTrackingJob(cancelled, incomingJob, true /* writeBack */);
synchronized (mLock) {
+ if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
+ cancelled.unprepareLocked(ActivityManager.getService());
+ stopTrackingJobLocked(cancelled, incomingJob, true /* writeBack */);
// Remove from pending queue.
if (mPendingJobs.remove(cancelled)) {
mJobPackageTracker.noteNonpending(cancelled);
}
// Cancel if running.
stopJobOnServiceContextLocked(cancelled, JobParameters.REASON_CANCELED);
- reportActive();
+ reportActiveLocked();
}
}
@@ -773,7 +776,7 @@
}
}
- void reportActive() {
+ void reportActiveLocked() {
// active is true if pending queue contains jobs OR some job is running.
boolean active = mPendingJobs.size() > 0;
if (mPendingJobs.size() <= 0) {
@@ -895,20 +898,18 @@
* {@link com.android.server.job.JobStore}, and make sure all the relevant controllers know
* about.
*/
- private void startTrackingJob(JobStatus jobStatus, JobStatus lastJob) {
- synchronized (mLock) {
- if (!jobStatus.isPrepared()) {
- Slog.wtf(TAG, "Not yet prepared when started tracking: " + jobStatus);
- }
- final boolean update = mJobs.add(jobStatus);
- if (mReadyToRock) {
- for (int i = 0; i < mControllers.size(); i++) {
- StateController controller = mControllers.get(i);
- if (update) {
- controller.maybeStopTrackingJobLocked(jobStatus, null, true);
- }
- controller.maybeStartTrackingJobLocked(jobStatus, lastJob);
+ private void startTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
+ if (!jobStatus.isPreparedLocked()) {
+ Slog.wtf(TAG, "Not yet prepared when started tracking: " + jobStatus);
+ }
+ final boolean update = mJobs.add(jobStatus);
+ if (mReadyToRock) {
+ for (int i = 0; i < mControllers.size(); i++) {
+ StateController controller = mControllers.get(i);
+ if (update) {
+ controller.maybeStopTrackingJobLocked(jobStatus, null, true);
}
+ controller.maybeStartTrackingJobLocked(jobStatus, lastJob);
}
}
}
@@ -917,19 +918,20 @@
* Called when we want to remove a JobStatus object that we've finished executing. Returns the
* object removed.
*/
- private boolean stopTrackingJob(JobStatus jobStatus, JobStatus incomingJob,
+ private boolean stopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
boolean writeBack) {
- synchronized (mLock) {
- // Remove from store as well as controllers.
- final boolean removed = mJobs.remove(jobStatus, writeBack);
- if (removed && mReadyToRock) {
- for (int i=0; i<mControllers.size(); i++) {
- StateController controller = mControllers.get(i);
- controller.maybeStopTrackingJobLocked(jobStatus, incomingJob, false);
- }
+ // Deal with any remaining work items in the old job.
+ jobStatus.stopTrackingJobLocked(incomingJob);
+
+ // Remove from store as well as controllers.
+ final boolean removed = mJobs.remove(jobStatus, writeBack);
+ if (removed && mReadyToRock) {
+ for (int i=0; i<mControllers.size(); i++) {
+ StateController controller = mControllers.get(i);
+ controller.maybeStopTrackingJobLocked(jobStatus, incomingJob, false);
}
- return removed;
}
+ return removed;
}
private boolean stopJobOnServiceContextLocked(JobStatus job, int reason) {
@@ -990,7 +992,7 @@
*
* @see JobHandler#maybeQueueReadyJobsForExecutionLockedH
*/
- private JobStatus getRescheduleJobForFailure(JobStatus failureToReschedule) {
+ private JobStatus getRescheduleJobForFailureLocked(JobStatus failureToReschedule) {
final long elapsedNowMillis = SystemClock.elapsedRealtime();
final JobInfo job = failureToReschedule.getJob();
@@ -1017,7 +1019,7 @@
JobStatus.NO_LATEST_RUNTIME, backoffAttempts);
for (int ic=0; ic<mControllers.size(); ic++) {
StateController controller = mControllers.get(ic);
- controller.rescheduleForFailure(newJob, failureToReschedule);
+ controller.rescheduleForFailureLocked(newJob, failureToReschedule);
}
return newJob;
}
@@ -1065,13 +1067,13 @@
* @param needsReschedule Whether the implementing class should reschedule this job.
*/
@Override
- public void onJobCompleted(JobStatus jobStatus, boolean needsReschedule) {
+ public void onJobCompletedLocked(JobStatus jobStatus, boolean needsReschedule) {
if (DEBUG) {
Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
}
// Do not write back immediately if this is a periodic job. The job may get lost if system
// shuts down before it is added back.
- if (!stopTrackingJob(jobStatus, null, !jobStatus.getJob().isPeriodic())) {
+ if (!stopTrackingJobLocked(jobStatus, null, !jobStatus.getJob().isPeriodic())) {
if (DEBUG) {
Slog.d(TAG, "Could not find job to remove. Was job removed while executing?");
}
@@ -1085,24 +1087,24 @@
// the old job after scheduling the new one, but since we have no lock held here
// that may cause ordering problems if the app removes jobStatus while in here.
if (needsReschedule) {
- JobStatus rescheduled = getRescheduleJobForFailure(jobStatus);
+ JobStatus rescheduled = getRescheduleJobForFailureLocked(jobStatus);
try {
- rescheduled.prepare(ActivityManager.getService());
+ rescheduled.prepareLocked(ActivityManager.getService());
} catch (SecurityException e) {
Slog.w(TAG, "Unable to regrant job permissions for " + rescheduled);
}
- startTrackingJob(rescheduled, jobStatus);
+ startTrackingJobLocked(rescheduled, jobStatus);
} else if (jobStatus.getJob().isPeriodic()) {
JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
try {
- rescheduledPeriodic.prepare(ActivityManager.getService());
+ rescheduledPeriodic.prepareLocked(ActivityManager.getService());
} catch (SecurityException e) {
Slog.w(TAG, "Unable to regrant job permissions for " + rescheduledPeriodic);
}
- startTrackingJob(rescheduledPeriodic, jobStatus);
+ startTrackingJobLocked(rescheduledPeriodic, jobStatus);
}
- jobStatus.unprepare(ActivityManager.getService());
- reportActive();
+ jobStatus.unprepareLocked(ActivityManager.getService());
+ reportActiveLocked();
mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
}
@@ -1410,7 +1412,7 @@
Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs.");
}
assignJobsToContextsLocked();
- reportActive();
+ reportActiveLocked();
}
}
}
@@ -1698,7 +1700,37 @@
long ident = Binder.clearCallingIdentity();
try {
- return JobSchedulerService.this.schedule(job, uid);
+ return JobSchedulerService.this.scheduleAsPackage(job, null, uid, null, -1, null);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ // IJobScheduler implementation
+ @Override
+ public int enqueue(JobInfo job, JobWorkItem work) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "Enqueueing job: " + job.toString() + " work: " + work);
+ }
+ final int pid = Binder.getCallingPid();
+ final int uid = Binder.getCallingUid();
+
+ enforceValidJobRequest(uid, job);
+ if (job.isPersisted()) {
+ throw new IllegalArgumentException("Can't enqueue work for persisted jobs");
+ }
+ if (work == null) {
+ throw new NullPointerException("work is null");
+ }
+
+ if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG);
+ }
+
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return JobSchedulerService.this.scheduleAsPackage(job, work, uid, null, -1, null);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1731,7 +1763,7 @@
long ident = Binder.clearCallingIdentity();
try {
- return JobSchedulerService.this.scheduleAsPackage(job, callerUid,
+ return JobSchedulerService.this.scheduleAsPackage(job, null, callerUid,
packageName, userId, tag);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 728ed72d..c7ef0e2 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -21,11 +21,11 @@
import android.app.job.JobParameters;
import android.app.job.IJobCallback;
import android.app.job.IJobService;
+import android.app.job.JobWorkItem;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
@@ -195,7 +195,7 @@
mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
mVerb = VERB_BINDING;
- scheduleOpTimeOut();
+ scheduleOpTimeOutLocked();
final Intent intent = new Intent().setComponent(job.getServiceComponent());
boolean binding = mContext.bindServiceAsUser(intent, this,
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,
@@ -208,7 +208,7 @@
mParams = null;
mExecutionStartTimeElapsed = 0L;
mVerb = VERB_FINISHED;
- removeOpTimeOut();
+ removeOpTimeOutLocked();
return false;
}
try {
@@ -297,6 +297,38 @@
mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, ongoing ? 1 : 0).sendToTarget();
}
+ @Override
+ public JobWorkItem dequeueWork(int jobId) {
+ if (!verifyCallingUid()) {
+ throw new SecurityException("Bad calling uid: " + Binder.getCallingUid());
+ }
+ JobWorkItem work = null;
+ boolean stillWorking = false;
+ synchronized (mLock) {
+ if (mRunningJob != null) {
+ work = mRunningJob.dequeueWorkLocked();
+ stillWorking = mRunningJob.hasExecutingWorkLocked();
+ }
+ }
+ if (work == null && !stillWorking) {
+ jobFinished(jobId, false);
+ }
+ return work;
+ }
+
+ @Override
+ public boolean completeWork(int jobId, int workId) {
+ if (!verifyCallingUid()) {
+ throw new SecurityException("Bad calling uid: " + Binder.getCallingUid());
+ }
+ synchronized (mLock) {
+ if (mRunningJob != null) {
+ return mRunningJob.completeWorkLocked(workId);
+ }
+ return false;
+ }
+ }
+
/**
* We acquire/release a wakelock on onServiceConnected/unbindService. This mirrors the work
* we intend to send to the client - we stop sending work when the service is unbound so until
@@ -378,46 +410,18 @@
public void handleMessage(Message message) {
switch (message.what) {
case MSG_SERVICE_BOUND:
- removeOpTimeOut();
- handleServiceBoundH();
+ doServiceBound();
break;
case MSG_CALLBACK:
- if (DEBUG) {
- Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob
- + " v:" + VERB_STRINGS[mVerb]);
- }
- removeOpTimeOut();
-
- if (mVerb == VERB_STARTING) {
- final boolean workOngoing = message.arg2 == 1;
- handleStartedH(workOngoing);
- } else if (mVerb == VERB_EXECUTING ||
- mVerb == VERB_STOPPING) {
- final boolean reschedule = message.arg2 == 1;
- handleFinishedH(reschedule);
- } else {
- if (DEBUG) {
- Slog.d(TAG, "Unrecognised callback: " + mRunningJob);
- }
- }
+ doCallback(message.arg2);
break;
case MSG_CANCEL:
- if (mVerb == VERB_FINISHED) {
- if (DEBUG) {
- Slog.d(TAG,
- "Trying to process cancel for torn-down context, ignoring.");
- }
- return;
- }
- mParams.setStopReason(message.arg1);
- if (message.arg1 == JobParameters.REASON_PREEMPT) {
- mPreferredUid = mRunningJob != null ? mRunningJob.getUid() :
- NO_PREFERRED_UID;
- }
- handleCancelH();
+ doCancel(message.arg1);
break;
case MSG_TIMEOUT:
- handleOpTimeoutH();
+ synchronized (mLock) {
+ handleOpTimeoutH();
+ }
break;
case MSG_SHUTDOWN_EXECUTION:
closeAndCleanupJobH(true /* needsReschedule */);
@@ -427,6 +431,55 @@
}
}
+ void doServiceBound() {
+ synchronized (mLock) {
+ removeOpTimeOutLocked();
+ handleServiceBoundH();
+ }
+ }
+
+ void doCallback(int arg2) {
+ synchronized (mLock) {
+ if (DEBUG) {
+ Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob
+ + " v:" + VERB_STRINGS[mVerb]);
+ }
+ removeOpTimeOutLocked();
+
+ if (mVerb == VERB_STARTING) {
+ final boolean workOngoing = arg2 == 1;
+ handleStartedH(workOngoing);
+ } else if (mVerb == VERB_EXECUTING ||
+ mVerb == VERB_STOPPING) {
+ final boolean reschedule = arg2 == 1;
+ handleFinishedH(reschedule);
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, "Unrecognised callback: " + mRunningJob);
+ }
+ }
+ }
+ }
+
+ void doCancel(int arg1) {
+ synchronized (mLock) {
+ if (mVerb == VERB_FINISHED) {
+ if (DEBUG) {
+ Slog.d(TAG,
+ "Trying to process cancel for torn-down context, ignoring.");
+ }
+ return;
+ }
+ mParams.setStopReason(arg1);
+ if (arg1 == JobParameters.REASON_PREEMPT) {
+ mPreferredUid = mRunningJob != null ? mRunningJob.getUid() :
+ NO_PREFERRED_UID;
+ }
+ handleCancelH();
+ }
+
+ }
+
/** Start the job on the service. */
private void handleServiceBoundH() {
if (DEBUG) {
@@ -448,7 +501,7 @@
}
try {
mVerb = VERB_STARTING;
- scheduleOpTimeOut();
+ scheduleOpTimeOutLocked();
service.startJob(mParams);
} catch (Exception e) {
// We catch 'Exception' because client-app malice or bugs might induce a wide
@@ -483,7 +536,7 @@
handleCancelH();
return;
}
- scheduleOpTimeOut();
+ scheduleOpTimeOutLocked();
break;
default:
Slog.e(TAG, "Handling started job but job wasn't starting! Was "
@@ -587,7 +640,7 @@
* VERB_STOPPING.
*/
private void sendStopMessageH() {
- removeOpTimeOut();
+ removeOpTimeOutLocked();
if (mVerb != VERB_EXECUTING) {
Slog.e(TAG, "Sending onStopJob for a job that isn't started. " + mRunningJob);
closeAndCleanupJobH(false /* reschedule */);
@@ -595,7 +648,7 @@
}
try {
mVerb = VERB_STOPPING;
- scheduleOpTimeOut();
+ scheduleOpTimeOutLocked();
service.stopJob(mParams);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending onStopJob to client.", e);
@@ -635,13 +688,13 @@
mCancelled.set(false);
service = null;
mAvailable = true;
+ removeOpTimeOutLocked();
+ removeMessages(MSG_CALLBACK);
+ removeMessages(MSG_SERVICE_BOUND);
+ removeMessages(MSG_CANCEL);
+ removeMessages(MSG_SHUTDOWN_EXECUTION);
+ mCompletedListener.onJobCompletedLocked(completedJob, reschedule);
}
- removeOpTimeOut();
- removeMessages(MSG_CALLBACK);
- removeMessages(MSG_SERVICE_BOUND);
- removeMessages(MSG_CANCEL);
- removeMessages(MSG_SHUTDOWN_EXECUTION);
- mCompletedListener.onJobCompleted(completedJob, reschedule);
}
}
@@ -650,8 +703,8 @@
* we haven't received a response in a certain amount of time, we want to give up and carry
* on with life.
*/
- private void scheduleOpTimeOut() {
- removeOpTimeOut();
+ private void scheduleOpTimeOutLocked() {
+ removeOpTimeOutLocked();
final long timeoutMillis;
switch (mVerb) {
@@ -678,7 +731,7 @@
}
- private void removeOpTimeOut() {
+ private void removeOpTimeOutLocked() {
mCallbackHandler.removeMessages(MSG_TIMEOUT);
}
}
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index c0264df..fcc0827 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -454,7 +454,7 @@
IActivityManager am = ActivityManager.getService();
for (int i=0; i<jobs.size(); i++) {
JobStatus js = jobs.get(i);
- js.prepare(am);
+ js.prepareLocked(am);
this.jobSet.add(js);
}
}
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
index 5d209fc..29f0e2c 100644
--- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -164,7 +164,7 @@
&& taskStatus.contentObserverJobInstance.mChangedAuthorities != null) {
// We are stopping this job, but it is going to be replaced by this given
// incoming job. We want to propagate our state over to it, so we don't
- // lose any content changes that had happend since the last one started.
+ // lose any content changes that had happened since the last one started.
// If there is a previous job associated with the new job, propagate over
// any pending content URI trigger reports.
if (incomingJob.contentObserverJobInstance == null) {
@@ -195,16 +195,14 @@
}
@Override
- public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
+ public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) {
if (failureToReschedule.hasContentTriggerConstraint()
&& newJob.hasContentTriggerConstraint()) {
- synchronized (mLock) {
- // Our job has failed, and we are scheduling a new job for it.
- // Copy the last reported content changes in to the new job, so when
- // we schedule the new one we will pick them up and report them again.
- newJob.changedAuthorities = failureToReschedule.changedAuthorities;
- newJob.changedUris = failureToReschedule.changedUris;
- }
+ // Our job has failed, and we are scheduling a new job for it.
+ // Copy the last reported content changes in to the new job, so when
+ // we schedule the new one we will pick them up and report them again.
+ newJob.changedAuthorities = failureToReschedule.changedAuthorities;
+ newJob.changedUris = failureToReschedule.changedUris;
}
}
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index d27d0e5..4cdce5f 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -19,6 +19,7 @@
import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.job.JobInfo;
+import android.app.job.JobWorkItem;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.ContentProvider;
@@ -35,6 +36,7 @@
import android.util.TimeUtils;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Arrays;
/**
@@ -126,6 +128,14 @@
public int lastEvaluatedPriority;
+ // If non-null, this is work that has been enqueued for the job.
+ public ArrayList<JobWorkItem> pendingWork;
+
+ // If non-null, this is work that is currently being executed.
+ public ArrayList<JobWorkItem> executingWork;
+
+ public int nextPendingWorkId = 1;
+
// Used by shell commands
public int overrideState = 0;
@@ -256,7 +266,59 @@
earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis);
}
- public void prepare(IActivityManager am) {
+ public void enqueueWorkLocked(JobWorkItem work) {
+ if (pendingWork == null) {
+ pendingWork = new ArrayList<>();
+ }
+ work.setWorkId(nextPendingWorkId);
+ nextPendingWorkId++;
+ pendingWork.add(work);
+ }
+
+ public JobWorkItem dequeueWorkLocked() {
+ if (pendingWork != null && pendingWork.size() > 0) {
+ JobWorkItem work = pendingWork.remove(0);
+ if (work != null) {
+ if (executingWork == null) {
+ executingWork = new ArrayList<>();
+ }
+ executingWork.add(work);
+ }
+ return work;
+ }
+ return null;
+ }
+
+ public boolean hasExecutingWorkLocked() {
+ return executingWork != null && executingWork.size() > 0;
+ }
+
+ public boolean completeWorkLocked(int workId) {
+ if (executingWork != null) {
+ final int N = executingWork.size();
+ for (int i = 0; i < N; i++) {
+ if (executingWork.get(i).getWorkId() == workId) {
+ executingWork.remove(i);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void stopTrackingJobLocked(JobStatus incomingJob) {
+ if (incomingJob != null) {
+ // We are replacing with a new job -- transfer the work!
+ incomingJob.pendingWork = pendingWork;
+ pendingWork = null;
+ incomingJob.nextPendingWorkId = nextPendingWorkId;
+ } else {
+ // We are completely stopping the job... need to clean up work.
+ // XXX remove perms when that is impl.
+ }
+ }
+
+ public void prepareLocked(IActivityManager am) {
if (prepared) {
Slog.wtf(TAG, "Already prepared: " + this);
return;
@@ -271,7 +333,7 @@
}
}
- public void unprepare(IActivityManager am) {
+ public void unprepareLocked(IActivityManager am) {
if (!prepared) {
Slog.wtf(TAG, "Hasn't been prepared: " + this);
return;
@@ -288,7 +350,7 @@
}
}
- public boolean isPrepared() {
+ public boolean isPreparedLocked() {
return prepared;
}
@@ -854,6 +916,22 @@
}
}
}
+ if (pendingWork != null && pendingWork.size() > 0) {
+ pw.print(prefix); pw.println("Pending work:");
+ for (int i = 0; i < pendingWork.size(); i++) {
+ JobWorkItem work = pendingWork.get(i);
+ pw.print(prefix); pw.print(" #"); pw.print(i); pw.print(": #");
+ pw.print(work.getWorkId()); pw.print(" "); pw.println(work.getIntent());
+ }
+ }
+ if (executingWork != null && executingWork.size() > 0) {
+ pw.print(prefix); pw.println("Executing work:");
+ for (int i = 0; i < executingWork.size(); i++) {
+ JobWorkItem work = executingWork.get(i);
+ pw.print(prefix); pw.print(" #"); pw.print(i); pw.print(": #");
+ pw.print(work.getWorkId()); pw.print(" "); pw.println(work.getIntent());
+ }
+ }
pw.print(prefix); pw.print("Earliest run time: ");
pw.println(formatRunTime(earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME));
pw.print(prefix); pw.print("Latest run time: ");
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 1721fb9..497faab 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -61,7 +61,7 @@
/**
* Called when a new job is being created to reschedule an old failed job.
*/
- public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
+ public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) {
}
public abstract void dumpControllerStateLocked(PrintWriter pw, int filterUid);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 2e499f1..9157c4e 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2992,7 +2992,12 @@
// Skip if it had no restrictions to begin with
if ((oldRules & MASK_ALL_NETWORKS) == 0) continue;
}
- updateRulesForPowerRestrictionsUL(uid, oldRules, paroled);
+ final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldRules, paroled);
+ if (newUidRules == RULE_NONE) {
+ mUidRules.delete(uid);
+ } else {
+ mUidRules.put(uid, newUidRules);
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 3c46e05..2c7a61b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2695,7 +2695,9 @@
Preconditions.checkNotNull(channel);
ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
- checkHasCompanionDevice(info);
+ if (!hasCompanionDevice(info)) {
+ throw new SecurityException(info + " does not have access");
+ }
int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
updateNotificationChannelInt(pkg, uid, channel, true);
@@ -2705,7 +2707,9 @@
public ParceledListSlice<NotificationChannel> getNotificationChannelsFromPrivilegedListener(
INotificationListener token, String pkg) throws RemoteException {
ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
- checkHasCompanionDevice(info);
+ if (!hasCompanionDevice(info)) {
+ throw new SecurityException(info + " does not have access");
+ }
int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
return mRankingHelper.getNotificationChannels(pkg, uid, false /* includeDeleted */);
@@ -2716,7 +2720,9 @@
getNotificationChannelGroupsFromPrivilegedListener(
INotificationListener token, String pkg) throws RemoteException {
ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
- checkHasCompanionDevice(info);
+ if (!hasCompanionDevice(info)) {
+ throw new SecurityException(info + " does not have access");
+ }
List<NotificationChannelGroup> groups = new ArrayList<>();
int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
@@ -4655,15 +4661,28 @@
channels, overridePeople, snoozeCriteria, showBadge);
}
- private void checkHasCompanionDevice(ManagedServiceInfo info) throws RemoteException {
+ boolean hasCompanionDevice(ManagedServiceInfo info) {
if (mCompanionManager == null) {
mCompanionManager = ICompanionDeviceManager.Stub.asInterface(
ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE));
}
- if (ArrayUtils.isEmpty(mCompanionManager.getAssociations(
- info.component.getPackageName(), info.userid))) {
- throw new SecurityException("Disallowed call from " + info.component);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ List<String> associations = mCompanionManager.getAssociations(
+ info.component.getPackageName(), info.userid);
+ if (!ArrayUtils.isEmpty(associations)) {
+ return true;
+ }
+ } catch (SecurityException se) {
+ // Not a privileged listener
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Cannot reach companion device service", re);
+ } catch (Exception e) {
+ Slog.e(TAG, "Cannot verify listener " + info, e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
+ return false;
}
private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
@@ -4996,23 +5015,19 @@
return;
}
for (final ManagedServiceInfo serviceInfo : getServices()) {
- if (!serviceInfo.isEnabledForCurrentProfiles()) {
+ if (!serviceInfo.enabledAndUserMatches(UserHandle.getCallingUserId())) {
continue;
}
- try {
- checkHasCompanionDevice(serviceInfo);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyNotificationChannelChanged(serviceInfo, pkg, channel,
- modificationType);
- }
- });
- } catch (SecurityException se) {
- // Not a privileged listener; do not notify
- } catch (RemoteException e) {
- Slog.e(TAG, "Cannot reach companion device service", e);
+ if (!hasCompanionDevice(serviceInfo)) {
+ continue;
}
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ notifyNotificationChannelChanged(serviceInfo, pkg, channel,
+ modificationType);
+ }
+ });
}
}
@@ -5022,23 +5037,19 @@
return;
}
for (final ManagedServiceInfo serviceInfo : getServices()) {
- if (!serviceInfo.isEnabledForCurrentProfiles()) {
+ if (!serviceInfo.enabledAndUserMatches(UserHandle.getCallingUserId())) {
continue;
}
- try {
- checkHasCompanionDevice(serviceInfo);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyNotificationChannelGroupChanged(serviceInfo, pkg, group,
- modificationType);
- }
- });
- } catch (SecurityException se) {
- // Not a privileged listener; do not notify
- } catch (RemoteException e) {
- Slog.e(TAG, "Cannot reach companion device service", e);
+ if (!hasCompanionDevice(serviceInfo)) {
+ continue;
}
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ notifyNotificationChannelGroupChanged(serviceInfo, pkg, group,
+ modificationType);
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index b043230..b7d3173 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -376,7 +376,20 @@
pw.println(prefix + "fullscreenIntent=" + notification.fullScreenIntent);
pw.println(prefix + "contentIntent=" + notification.contentIntent);
pw.println(prefix + "deleteIntent=" + notification.deleteIntent);
- pw.println(prefix + "tickerText=" + notification.tickerText);
+
+ pw.print(prefix + "tickerText=");
+ if (!TextUtils.isEmpty(notification.tickerText)) {
+ final String ticker = notification.tickerText.toString();
+ if (redact) {
+ // if the string is long enough, we allow ourselves a few bytes for debugging
+ pw.print(ticker.length() > 16 ? ticker.substring(0,8) : "");
+ pw.println("...");
+ } else {
+ pw.println(ticker);
+ }
+ } else {
+ pw.println("null");
+ }
pw.println(prefix + "contentView=" + notification.contentView);
pw.println(prefix + String.format("color=0x%08x", notification.color));
pw.println(prefix + "timeout=" + TimeUtils.formatForLogging(notification.getTimeout()));
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 818c3ad..0e1f485 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -71,6 +71,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -754,12 +755,17 @@
// restarted before we received USER_REMOVED. Remove data for
// users that will not exist after the system is ready.
- final List<UserInfo> deadUsers = getDeadUsers();
- final int N = deadUsers.size();
- for (int i = 0; i < N; i++) {
- final UserInfo deadUser = deadUsers.get(i);
- final int userId = deadUser.getUserHandle().getIdentifier();
- mSettings.removeUser(userId);
+ final List<UserInfo> liveUsers = mUserManager.getUsers(true /*excludeDying*/);
+ final int[] liveUserIds = new int[liveUsers.size()];
+ for (int i = 0; i < liveUsers.size(); i++) {
+ liveUserIds[i] = liveUsers.get(i).getUserHandle().getIdentifier();
+ }
+ Arrays.sort(liveUserIds);
+
+ for (int userId : mSettings.getUsers()) {
+ if (Arrays.binarySearch(liveUserIds, userId) < 0) {
+ mSettings.removeUser(userId);
+ }
}
} catch (IOException | XmlPullParserException e) {
Slog.e(TAG, "failed to restore overlay state", e);
@@ -767,13 +773,6 @@
}
}
- private List<UserInfo> getDeadUsers() {
- final List<UserInfo> users = mUserManager.getUsers(false);
- final List<UserInfo> onlyLiveUsers = mUserManager.getUsers(true);
- users.removeAll(onlyLiveUsers);
- return users;
- }
-
private static final class PackageManagerHelper implements
OverlayManagerServiceImpl.PackageManagerHelper {
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index b203674..5196c66 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -109,6 +109,10 @@
if (overlayPackage.isStaticOverlay ||
mDefaultOverlays.contains(overlayPackage.packageName)) {
// Enable this overlay by default.
+ if (DEBUG) {
+ Slog.d(TAG, "Enabling overlay " + overlayPackage.packageName
+ + " for user " + newUserId + " by default");
+ }
mSettings.setEnabled(overlayPackage.packageName, newUserId, true);
}
} else {
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index 72979f6..2f83793 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -16,11 +16,15 @@
package com.android.server.om;
+import static com.android.server.om.OverlayManagerService.DEBUG;
+import static com.android.server.om.OverlayManagerService.TAG;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.om.OverlayInfo;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
+import android.util.Slog;
import android.util.Xml;
import com.android.internal.util.FastXmlSerializer;
@@ -185,6 +189,10 @@
for (int i = 0; i < mItems.size(); i++) {
final SettingsItem item = mItems.get(i);
if (item.getUserId() == userId) {
+ if (DEBUG) {
+ Slog.d(TAG, "Removing overlay " + item.mPackageName + " for user " + userId
+ + " from settings because user was removed");
+ }
mItems.remove(i);
removed = true;
i--;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 71f700c..c25ab37 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -90,7 +90,6 @@
import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.internal.util.ArrayUtils.appendInt;
-import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
@@ -164,7 +163,6 @@
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
-import android.content.pm.SELinuxUtil;
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
@@ -222,6 +220,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Base64;
+import android.util.BootTimingsTraceLog;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.ExceptionUtils;
@@ -273,7 +272,6 @@
import com.android.server.SystemServerInitThreadPool;
import com.android.server.Watchdog;
import com.android.server.net.NetworkPolicyManagerInternal;
-import com.android.server.pm.BackgroundDexOptService;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.PermissionsState.PermissionState;
import com.android.server.pm.Settings.DatabaseVersion;
@@ -299,7 +297,6 @@
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
@@ -2726,15 +2723,18 @@
UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
true /* onlyCoreApps */);
mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "fixup");
+ BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
+ Trace.TRACE_TAG_PACKAGE_MANAGER);
+ traceLog.traceBegin("AppDataFixup");
try {
mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
} catch (InstallerException e) {
Slog.w(TAG, "Trouble fixing GIDs", e);
}
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ traceLog.traceEnd();
+ traceLog.traceBegin("AppDataPrepare");
if (deferPackages == null || deferPackages.isEmpty()) {
return;
}
@@ -2755,6 +2755,7 @@
count++;
}
}
+ traceLog.traceEnd();
Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
}, "prepareAppData");
@@ -5725,9 +5726,6 @@
Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck) {
final int callingUser = UserHandle.getCallingUserId();
- if (callingUser != UserHandle.USER_SYSTEM) {
- return false;
- }
if (mInstantAppResolverConnection == null) {
return false;
}
@@ -6338,19 +6336,24 @@
Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
}
final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
- ephemeralInstaller.activityInfo = new ActivityInfo(mInstantAppInstallerActivity);
- ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
- ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
- // make sure this resolver is the default
- ephemeralInstaller.isDefault = true;
- ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
- | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
- // add a non-generic filter
- ephemeralInstaller.filter = new IntentFilter(intent.getAction());
- ephemeralInstaller.filter.addDataPath(
- intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
- ephemeralInstaller.instantAppAvailable = true;
- result.add(ephemeralInstaller);
+ final PackageSetting ps =
+ mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
+ if (ps != null) {
+ ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
+ mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
+ ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
+ ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
+ // make sure this resolver is the default
+ ephemeralInstaller.isDefault = true;
+ ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
+ | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
+ // add a non-generic filter
+ ephemeralInstaller.filter = new IntentFilter(intent.getAction());
+ ephemeralInstaller.filter.addDataPath(
+ intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
+ ephemeralInstaller.instantAppAvailable = true;
+ result.add(ephemeralInstaller);
+ }
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -20179,14 +20182,14 @@
public void onChange(boolean selfChange) {
mEphemeralAppsDisabled =
(Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
- (Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0);
+ (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
}
};
mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
.getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
false, co, UserHandle.USER_SYSTEM);
mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
- .getUriFor(Secure.WEB_ACTION_ENABLED), false, co, UserHandle.USER_SYSTEM);
+ .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
co.onChange(true);
// Disable any carrier apps. We do this very early in boot to prevent the apps from being
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a60dae7..cf597b05 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -46,6 +46,8 @@
import android.os.PowerSaveState;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
@@ -4027,6 +4029,14 @@
}
private final class BinderService extends IPowerManager.Stub {
+ @Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out,
+ FileDescriptor err, String[] args, ShellCallback callback,
+ ResultReceiver resultReceiver) {
+ (new PowerManagerShellCommand(this)).exec(
+ this, in, out, err, args, callback, resultReceiver);
+ }
+
@Override // Binder call
public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
String packageName, int uid) {
diff --git a/services/core/java/com/android/server/power/PowerManagerShellCommand.java b/services/core/java/com/android/server/power/PowerManagerShellCommand.java
new file mode 100644
index 0000000..46115d8
--- /dev/null
+++ b/services/core/java/com/android/server/power/PowerManagerShellCommand.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import android.content.Intent;
+import android.os.IPowerManager;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+
+import java.io.PrintWriter;
+
+class PowerManagerShellCommand extends ShellCommand {
+ private static final int LOW_POWER_MODE_ON = 1;
+
+ final IPowerManager mInterface;
+
+ PowerManagerShellCommand(IPowerManager service) {
+ mInterface = service;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+
+ final PrintWriter pw = getOutPrintWriter();
+ try {
+ switch(cmd) {
+ case "set-mode":
+ return runSetMode();
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ } catch (RemoteException e) {
+ pw.println("Remote exception: " + e);
+ }
+ return -1;
+ }
+
+ private int runSetMode() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ int mode = -1;
+ try {
+ mode = Integer.parseInt(getNextArgRequired());
+ } catch (RuntimeException ex) {
+ pw.println("Error: " + ex.toString());
+ return -1;
+ }
+ mInterface.setPowerSaveMode(mode == LOW_POWER_MODE_ON);
+ return 0;
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("Power manager (power) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println("");
+ pw.println(" set-mode MODE");
+ pw.println(" sets the power mode of the device to MODE.");
+ pw.println(" 1 turns low power mode on and 0 turns low power mode off.");
+ pw.println();
+ Intent.printIntentArgsHelp(pw , "");
+ }
+}
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 8c31731..8969771 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -18,7 +18,6 @@
import android.app.ActivityManager;
import android.app.AppGlobals;
-import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.ISearchManager;
import android.app.SearchManager;
@@ -29,7 +28,6 @@
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.os.Binder;
@@ -39,8 +37,6 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import android.speech.RecognitionService;
-import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
@@ -276,52 +272,6 @@
}
}
- private boolean isDefaultRecognizerPackage(String packageName) {
- ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(
- new Intent(RecognitionService.SERVICE_INTERFACE),
- PackageManager.GET_META_DATA);
- if (resolveInfo == null || resolveInfo.serviceInfo == null) {
- Log.w(TAG, "Unable to resolve default voice recognition service.");
- return false;
- }
- if (!TextUtils.isEmpty(packageName) && TextUtils.equals(packageName,
- resolveInfo.serviceInfo.packageName)) {
- return true;
- }
- return false;
- }
-
- private ComponentName getLegacyAssistReceiverComponent(int userHandle) {
- try {
- userHandle = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userHandle, true, false,
- "getLegacyAssistReceiverComponent", null);
- IPackageManager pm = AppGlobals.getPackageManager();
- Intent assistIntent = new Intent(Intent.ACTION_ASSIST);
- ParceledListSlice<ResolveInfo> infoParceledList =
- pm.queryIntentReceivers(assistIntent,
- assistIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
- PackageManager.MATCH_DEFAULT_ONLY, userHandle);
- if (infoParceledList != null) {
- List<ResolveInfo> infoList = infoParceledList.getList();
- if (infoList != null && infoList.size() > 0) {
- if (isDefaultRecognizerPackage(
- infoList.get(0).activityInfo.applicationInfo.packageName)) {
- return new ComponentName(
- infoList.get(0).activityInfo.applicationInfo.packageName,
- infoList.get(0).activityInfo.name);
- }
- }
- }
- } catch (RemoteException re) {
- // Local call
- Log.e(TAG, "RemoteException in getLegacyAssistReceiverComponent: " + re);
- } catch (Exception e) {
- Log.e(TAG, "Exception in getLegacyAssistReceiverComponent: " + e);
- }
- return null;
- }
-
private ComponentName getLegacyAssistComponent(int userHandle) {
try {
userHandle = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
@@ -348,7 +298,7 @@
@Override
public boolean launchLegacyAssist(String hint, int userHandle, Bundle args) {
- ComponentName comp = getLegacyAssistReceiverComponent(userHandle);
+ ComponentName comp = getLegacyAssistComponent(userHandle);
if (comp == null) {
return false;
}
@@ -356,13 +306,9 @@
try {
Intent intent = new Intent(Intent.ACTION_ASSIST);
intent.setComponent(comp);
- if (args != null) {
- intent.putExtras(args);
- }
IActivityManager am = ActivityManager.getService();
- return am.broadcastIntent(null, intent, null, null, 0, null, null, null,
- AppOpsManager.OP_NONE, null, false, false,
- userHandle) == ActivityManager.BROADCAST_SUCCESS;
+ return am.launchAssistIntent(intent, ActivityManager.ASSIST_CONTEXT_BASIC, hint,
+ userHandle, args);
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
index 4035ade..1783dcc 100644
--- a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
+++ b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
@@ -73,7 +73,6 @@
final int userId = UserHandle.myUserId();
UserEnvironment environment = new UserEnvironment(userId);
LogRunnable task = new LogRunnable();
- task.setRootDirectory(environment.getExternalStorageDirectory());
task.setDownloadsDirectory(
environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
task.setSystemSize(FileCollector.getSystemSize(this));
@@ -127,14 +126,10 @@
private JobParameters mParams;
private AppCollector mCollector;
private File mOutputFile;
- private File mRootDirectory;
private File mDownloadsDirectory;
+ private Context mContext;
private long mSystemSize;
- public void setRootDirectory(File file) {
- mRootDirectory = file;
- }
-
public void setDownloadsDirectory(File file) {
mDownloadsDirectory = file;
}
@@ -151,14 +146,25 @@
mSystemSize = size;
}
+ public void setContext(Context context) {
+ mContext = context;
+ }
+
public void setJobService(JobService jobService, JobParameters params) {
mJobService = jobService;
mParams = params;
}
public void run() {
- FileCollector.MeasurementResult mainCategories =
- FileCollector.getMeasurementResult(mRootDirectory);
+ FileCollector.MeasurementResult mainCategories;
+ try {
+ mainCategories = FileCollector.getMeasurementResult(mContext);
+ } catch (IllegalStateException e) {
+ // This can occur if installd has an issue.
+ Log.e(TAG, "Error while measuring storage", e);
+ finishJob(true);
+ return;
+ }
FileCollector.MeasurementResult downloads =
FileCollector.getMeasurementResult(mDownloadsDirectory);
@@ -168,12 +174,10 @@
needsReschedule = false;
logToFile(mainCategories, downloads, stats, mSystemSize);
} else {
- Log.w("TAG", "Timed out while fetching package stats.");
+ Log.w(TAG, "Timed out while fetching package stats.");
}
- if (mJobService != null) {
- mJobService.jobFinished(mParams, needsReschedule);
- }
+ finishJob(needsReschedule);
}
private void logToFile(MeasurementResult mainCategories, MeasurementResult downloads,
@@ -187,5 +191,11 @@
Log.e(TAG, "Exception while writing opportunistic disk file cache.", e);
}
}
+
+ private void finishJob(boolean needsReschedule) {
+ if (mJobService != null) {
+ mJobService.jobFinished(mParams, needsReschedule);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/storage/FileCollector.java b/services/core/java/com/android/server/storage/FileCollector.java
index 90f9f139..04f25a4 100644
--- a/services/core/java/com/android/server/storage/FileCollector.java
+++ b/services/core/java/com/android/server/storage/FileCollector.java
@@ -17,8 +17,11 @@
package com.android.server.storage;
import android.annotation.IntDef;
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.util.ArrayMap;
@@ -154,8 +157,29 @@
}
/**
+ * Returns the file categorization result for the primary internal storage UUID.
+ *
+ * @param context
+ */
+ public static MeasurementResult getMeasurementResult(Context context) {
+ MeasurementResult result = new MeasurementResult();
+ StorageStatsManager ssm =
+ (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);
+ ExternalStorageStats stats =
+ ssm.queryExternalStatsForUser(
+ StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.of(context.getUserId()));
+ result.imagesSize = stats.getImageBytes();
+ result.videosSize = stats.getVideoBytes();
+ result.audioSize = stats.getAudioBytes();
+ result.miscSize =
+ stats.getTotalBytes() - result.imagesSize - result.videosSize - result.audioSize;
+ return result;
+ }
+
+ /**
* Returns the size of a system for a given context. This is done by finding the difference
* between the shared data and the total primary storage size.
+ *
* @param context Context to use to get storage information.
*/
public static long getSystemSize(Context context) {
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index e26914e..bde2111 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -449,7 +449,8 @@
public boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
- IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning) {
+ IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
+ boolean allowTaskSnapshot) {
synchronized(mWindowMap) {
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "setAppStartingWindow: token=" + mToken
+ " pkg=" + pkg + " transferFrom=" + transferFrom);
@@ -469,7 +470,8 @@
return false;
}
- final int type = getStartingWindowType(newTask, taskSwitch, processRunning);
+ final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
+ allowTaskSnapshot);
if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
return createSnapshot();
@@ -539,10 +541,11 @@
return true;
}
- private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning) {
+ private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
+ boolean allowTaskSnapshot) {
if (newTask || !processRunning) {
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
- } else if (taskSwitch) {
+ } else if (taskSwitch && allowTaskSnapshot) {
return STARTING_WINDOW_TYPE_SNAPSHOT;
} else {
return STARTING_WINDOW_TYPE_NONE;
@@ -612,13 +615,13 @@
}
}
- public void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
+ public void notifyAppResumed(boolean wasStopped) {
synchronized(mWindowMap) {
if (mContainer == null) {
Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + mToken);
return;
}
- mContainer.notifyAppResumed(wasStopped, allowSavedSurface);
+ mContainer.notifyAppResumed(wasStopped);
}
}
@@ -712,6 +715,10 @@
@Override
public String toString() {
- return "{AppWindowContainerController token=" + mToken + "}";
+ return "AppWindowContainerController{"
+ + " token=" + mToken
+ + " mContainer=" + mContainer
+ + " mListener=" + mListener
+ + "}";
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a8664a5..1fb34eb 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -582,16 +582,13 @@
* Notify that the app is now resumed, and it was not stopped before, perform a clean
* up of the surfaces
*/
- void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
+ void notifyAppResumed(boolean wasStopped) {
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
- + " allowSavedSurface=" + allowSavedSurface + " " + this);
+ + " " + this);
mAppStopped = false;
if (!wasStopped) {
destroySurfaces(true /*cleanupOnResume*/);
}
- if (!allowSavedSurface) {
- destroySavedSurfaces();
- }
}
/**
@@ -1553,6 +1550,9 @@
if (mPendingRelaunchCount != 0) {
pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
}
+ if (getController() != null) {
+ pw.print(prefix); pw.print("controller="); pw.println(getController());
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 48b01f4..fbb826d 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -162,12 +162,15 @@
if (top == null) {
return null;
}
+ final WindowState mainWindow = top.findMainWindow();
+ if (mainWindow == null) {
+ return null;
+ }
final GraphicBuffer buffer = top.mDisplayContent.screenshotApplicationsToBuffer(top.token,
-1, -1, false, 1.0f, false, true);
if (buffer == null) {
return null;
}
- final WindowState mainWindow = top.findMainWindow();
return new TaskSnapshot(buffer, top.getConfiguration().orientation,
minRect(mainWindow.mContentInsets, mainWindow.mStableInsets), false /* reduced */,
1f /* scale */);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8098eea..979af7e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -50,6 +50,7 @@
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -4411,4 +4412,14 @@
nowGone = true;
}
}
+
+ boolean usesRelativeZOrdering() {
+ if (!isChildWindow()) {
+ return false;
+ } else if (mAttrs.type == TYPE_APPLICATION_MEDIA_OVERLAY) {
+ return true;
+ } else {
+ return false;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a7f6db1..ae17d08 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -714,7 +714,16 @@
}
// Start a new transaction and apply position & offset.
- mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, getLayerStack(), mAnimLayer);
+
+ mService.openSurfaceTransaction();
+ try {
+ mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top, false);
+ mSurfaceController.setLayerStackInTransaction(getLayerStack());
+ mSurfaceController.setLayer(mAnimLayer);
+ } finally {
+ mService.closeSurfaceTransaction();
+ }
+
mLastHidden = true;
if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
@@ -1521,12 +1530,13 @@
+ "," + mDsDy + "*" + w.mVScale + "]", false);
boolean prepared =
- mSurfaceController.prepareToShowInTransaction(mShownAlpha, mAnimLayer,
+ mSurfaceController.prepareToShowInTransaction(mShownAlpha,
mDsDx * w.mHScale * mExtraHScale,
mDtDx * w.mVScale * mExtraVScale,
mDtDy * w.mHScale * mExtraHScale,
mDsDy * w.mVScale * mExtraVScale,
recoveringMemory);
+ mSurfaceController.setLayer(mAnimLayer);
if (prepared && mLastHidden && mDrawState == HAS_DRAWN) {
if (showSurfaceRobustlyLocked()) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index adf4501..edbdf8b 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -163,32 +163,6 @@
}
}
- void setPositionAndLayer(float left, float top, int layerStack, int layer) {
- mService.openSurfaceTransaction();
- try {
- mSurfaceX = left;
- mSurfaceY = top;
-
- try {
- if (SHOW_TRANSACTIONS) logSurface(
- "POS (setPositionAndLayer) @ (" + left + "," + top + ")", null);
- mSurfaceControl.setPosition(left, top);
- mSurfaceControl.setLayerStack(layerStack);
-
- mSurfaceControl.setLayer(layer);
- mSurfaceControl.setAlpha(0);
- setShown(false);
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error creating surface in " + this, e);
- mAnimator.reclaimSomeSurfaceMemory("create-init", true);
- }
- } finally {
- mService.closeSurfaceTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- "<<< CLOSE TRANSACTION setPositionAndLayer");
- }
- }
-
void destroyInTransaction() {
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8));
@@ -269,7 +243,15 @@
if (mSurfaceControl != null) {
mService.openSurfaceTransaction();
try {
- mSurfaceControl.setLayer(layer);
+ if (mAnimator.mWin.usesRelativeZOrdering()) {
+ mSurfaceControl.setRelativeLayer(
+ mAnimator.mWin.getParentWindow()
+ .mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
+ -1);
+ } else {
+ mSurfaceLayer = layer;
+ mSurfaceControl.setLayer(layer);
+ }
} finally {
mService.closeSurfaceTransaction();
}
@@ -363,15 +345,13 @@
return false;
}
- boolean prepareToShowInTransaction(float alpha, int layer,
+ boolean prepareToShowInTransaction(float alpha,
float dsdx, float dtdx, float dsdy,
float dtdy, boolean recoveringMemory) {
if (mSurfaceControl != null) {
try {
mSurfaceAlpha = alpha;
mSurfaceControl.setAlpha(alpha);
- mSurfaceLayer = layer;
- mSurfaceControl.setLayer(layer);
mLastDsdx = dsdx;
mLastDtdx = dtdx;
mLastDsdy = dsdy;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e47da55..67f1a0a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1541,9 +1541,11 @@
mSystemServiceManager.startService(RetailDemoModeService.class);
traceEnd();
- traceBeginAndSlog("StartAutoFillService");
- mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS);
- traceEnd();
+ if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOFILL)) {
+ traceBeginAndSlog("StartAutoFillService");
+ mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS);
+ traceEnd();
+ }
// It is now time to start up the app processes...
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 6aa8f3a..07e4bb8 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -59,10 +59,11 @@
import java.util.Arrays;
import java.util.List;
-import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
@@ -74,20 +75,21 @@
private NotificationManagerService mNotificationManagerService;
private INotificationManager mBinderService;
private NotificationManagerInternal mInternalService;
- private IPackageManager mPackageManager = mock(IPackageManager.class);
- private final PackageManager mPackageManagerClient = mock(PackageManager.class);
+ @Mock
+ private IPackageManager mPackageManager;
+ @Mock
+ private PackageManager mPackageManagerClient;
private Context mContext = InstrumentationRegistry.getTargetContext();
private final String PKG = mContext.getPackageName();
private TestableLooper mTestableLooper;
- private final RankingHelper mRankingHelper = mock(RankingHelper.class);
+ @Mock
+ private RankingHelper mRankingHelper;
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
- private NotificationManagerService.NotificationListeners mNotificationListeners =
- mock(NotificationManagerService.NotificationListeners.class);
- private ManagedServices.ManagedServiceInfo mListener =
- mNotificationListeners.new ManagedServiceInfo(
- null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
- private ICompanionDeviceManager mCompanionMgr = mock(ICompanionDeviceManager.class);
+ @Mock
+ private NotificationManagerService.NotificationListeners mNotificationListeners;
+ private ManagedServices.ManagedServiceInfo mListener;
+ @Mock private ICompanionDeviceManager mCompanionMgr;
// Use a Testable subclass so we can simulate calls from the system without failing.
private static class TestableNotificationManagerService extends NotificationManagerService {
@@ -102,6 +104,7 @@
@Before
@UiThreadTest
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
mNotificationManagerService = new TestableNotificationManagerService(mContext);
// MockPackageManager - default returns ApplicationInfo with matching calling UID
@@ -116,6 +119,8 @@
// Use this testable looper.
mTestableLooper = new TestableLooper(false);
+ mListener = mNotificationListeners.new ManagedServiceInfo(
+ null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
mPackageManagerClient, mockLightsManager, mNotificationListeners, mCompanionMgr);
@@ -631,4 +636,12 @@
verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
}
+
+ @Test
+ @UiThreadTest
+ public void testHasCompanionDevice_failure() throws Exception {
+ when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
+ new IllegalArgumentException());
+ mNotificationManagerService.hasCompanionDevice(mListener);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java b/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
index 3789086..81ce606 100644
--- a/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
@@ -20,15 +20,18 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.when;
import android.app.job.JobService;
-import android.app.job.JobParameters;
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.pm.PackageStats;
+import android.os.UserHandle;
import android.test.AndroidTestCase;
+import android.util.Log;
import com.android.server.storage.DiskStatsLoggingService.LogRunnable;
@@ -52,8 +55,10 @@
public class DiskStatsLoggingServiceTest extends AndroidTestCase {
@Rule public TemporaryFolder mTemporaryFolder;
@Rule public TemporaryFolder mDownloads;
- @Rule public TemporaryFolder mRootDirectory;
@Mock private AppCollector mCollector;
+ @Mock private JobService mJobService;
+ @Mock private StorageStatsManager mSsm;
+ private ExternalStorageStats mStorageStats;
private File mInputFile;
@@ -66,8 +71,10 @@
mInputFile = mTemporaryFolder.newFile();
mDownloads = new TemporaryFolder();
mDownloads.create();
- mRootDirectory = new TemporaryFolder();
- mRootDirectory.create();
+ mStorageStats = new ExternalStorageStats();
+ when(mSsm.queryExternalStatsForUser(isNull(String.class), any(UserHandle.class)))
+ .thenReturn(mStorageStats);
+ when(mJobService.getSystemService(anyString())).thenReturn(mSsm);
}
@Test
@@ -75,9 +82,9 @@
LogRunnable task = new LogRunnable();
task.setAppCollector(mCollector);
task.setDownloadsDirectory(mDownloads.getRoot());
- task.setRootDirectory(mRootDirectory.getRoot());
task.setLogOutputFile(mInputFile);
task.setSystemSize(0L);
+ task.setContext(mJobService);
task.run();
JSONObject json = getJsonOutput();
@@ -99,10 +106,10 @@
public void testPopulatedLogTask() throws Exception {
// Write data to directories.
writeDataToFile(mDownloads.newFile(), "lol");
- writeDataToFile(mRootDirectory.newFile("test.jpg"), "1234");
- writeDataToFile(mRootDirectory.newFile("test.mp4"), "12345");
- writeDataToFile(mRootDirectory.newFile("test.mp3"), "123456");
- writeDataToFile(mRootDirectory.newFile("test.whatever"), "1234567");
+ mStorageStats.audioBytes = 6L;
+ mStorageStats.imageBytes = 4L;
+ mStorageStats.videoBytes = 5L;
+ mStorageStats.totalBytes = 22L;
// Write apps.
ArrayList<PackageStats> apps = new ArrayList<>();
@@ -110,15 +117,16 @@
testApp.dataSize = 5L;
testApp.cacheSize = 55L;
testApp.codeSize = 10L;
+ testApp.userHandle = UserHandle.USER_SYSTEM;
apps.add(testApp);
- when(mCollector.getPackageStats(anyInt())).thenReturn(apps);
+ when(mCollector.getPackageStats(anyLong())).thenReturn(apps);
LogRunnable task = new LogRunnable();
task.setAppCollector(mCollector);
task.setDownloadsDirectory(mDownloads.getRoot());
- task.setRootDirectory(mRootDirectory.getRoot());
task.setLogOutputFile(mInputFile);
task.setSystemSize(10L);
+ task.setContext(mJobService);
task.run();
JSONObject json = getJsonOutput();
@@ -143,9 +151,9 @@
LogRunnable task = new LogRunnable();
task.setAppCollector(mCollector);
task.setDownloadsDirectory(mDownloads.getRoot());
- task.setRootDirectory(mRootDirectory.getRoot());
task.setLogOutputFile(mInputFile);
task.setSystemSize(10L);
+ task.setContext(mJobService);
task.run();
// No exception should be thrown.
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index 3c8bf20..d206407 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -97,7 +97,7 @@
final WindowTestUtils.TestAppWindowContainerController controller =
createAppWindowController();
controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
- android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
+ android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
waitUntilHandlersIdle();
final AppWindowToken atoken = controller.getAppWindowToken();
assertHasStartingWindow(atoken);
@@ -113,11 +113,11 @@
final WindowTestUtils.TestAppWindowContainerController controller2 =
createAppWindowController();
controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
- android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
+ android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
waitUntilHandlersIdle();
controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
- true, true, false);
+ true, true, false, true);
waitUntilHandlersIdle();
assertNoStartingWindow(controller1.getAppWindowToken());
assertHasStartingWindow(controller2.getAppWindowToken());
@@ -134,10 +134,10 @@
// Surprise, ...! Transfer window in the middle of the creation flow.
controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
- true, true, false);
+ true, true, false, true);
});
controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
- android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
+ android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
waitUntilHandlersIdle();
assertNoStartingWindow(controller1.getAppWindowToken());
assertHasStartingWindow(controller2.getAppWindowToken());
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 77da897..f9b754b0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3650,9 +3650,28 @@
*
* @param AID Application id. See ETSI 102.221 and 101.220.
* @return an IccOpenLogicalChannelResponse object.
+ * @deprecated Replaced by {@link #iccOpenLogicalChannel(String, int)}
*/
+ @Deprecated
public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID) {
- return iccOpenLogicalChannel(getSubId(), AID);
+ return iccOpenLogicalChannel(getSubId(), AID, -1);
+ }
+
+ /**
+ * Opens a logical channel to the ICC card.
+ *
+ * Input parameters equivalent to TS 27.007 AT+CCHO command.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+ * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+ *
+ * @param AID Application id. See ETSI 102.221 and 101.220.
+ * @param p2 P2 parameter (described in ISO 7816-4).
+ * @return an IccOpenLogicalChannelResponse object.
+ */
+ public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID, int p2) {
+ return iccOpenLogicalChannel(getSubId(), AID, p2);
}
/**
@@ -3666,14 +3685,15 @@
*
* @param subId The subscription to use.
* @param AID Application id. See ETSI 102.221 and 101.220.
+ * @param p2 P2 parameter (described in ISO 7816-4).
* @return an IccOpenLogicalChannelResponse object.
* @hide
*/
- public IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID) {
+ public IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID, int p2) {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.iccOpenLogicalChannel(subId, AID);
+ return telephony.iccOpenLogicalChannel(subId, AID, p2);
} catch (RemoteException ex) {
} catch (NullPointerException ex) {
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index db7e417..13a25ca5 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -623,9 +623,10 @@
*
* @param subId The subscription to use.
* @param AID Application id. See ETSI 102.221 and 101.220.
+ * @param p2 P2 parameter (described in ISO 7816-4).
* @return an IccOpenLogicalChannelResponse object.
*/
- IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID);
+ IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID, int p2);
/**
* Closes a previously opened logical channel to the ICC card.
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 6e0809e..3d76439 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -87,6 +87,7 @@
Maybe<std::string> generate_java_class_path;
Maybe<std::string> custom_java_package;
std::set<std::string> extra_java_packages;
+ Maybe<std::string> generate_text_symbols_path;
Maybe<std::string> generate_proguard_rules_path;
Maybe<std::string> generate_main_dex_proguard_rules_path;
bool generate_non_final_ids = false;
@@ -837,8 +838,8 @@
}
bool WriteJavaFile(ResourceTable* table, const StringPiece& package_name_to_generate,
- const StringPiece& out_package,
- const JavaClassGeneratorOptions& java_options) {
+ const StringPiece& out_package, const JavaClassGeneratorOptions& java_options,
+ const Maybe<std::string> out_text_symbols_path = {}) {
if (!options_.generate_java_class_path) {
return true;
}
@@ -861,8 +862,20 @@
return false;
}
+ std::unique_ptr<std::ofstream> fout_text;
+ if (out_text_symbols_path) {
+ fout_text =
+ util::make_unique<std::ofstream>(out_text_symbols_path.value(), std::ofstream::binary);
+ if (!*fout_text) {
+ context_->GetDiagnostics()->Error(
+ DiagMessage() << "failed writing to '" << out_text_symbols_path.value()
+ << "': " << android::base::SystemErrorCodeToString(errno));
+ return false;
+ }
+ }
+
JavaClassGenerator generator(context_, table, java_options);
- if (!generator.Generate(package_name_to_generate, out_package, &fout)) {
+ if (!generator.Generate(package_name_to_generate, out_package, &fout, fout_text.get())) {
context_->GetDiagnostics()->Error(DiagMessage(out_path) << generator.getError());
return false;
}
@@ -1683,7 +1696,8 @@
std::move(packages_to_callback);
}
- if (!WriteJavaFile(&final_table_, actual_package, output_package, options)) {
+ if (!WriteJavaFile(&final_table_, actual_package, output_package, options,
+ options_.generate_text_symbols_path)) {
return 1;
}
}
@@ -1785,9 +1799,9 @@
.OptionalSwitch("-z", "Require localization of strings marked 'suggested'.",
&require_localization)
.OptionalFlagList("-c",
- "Comma separated list of configurations to include. The default\n"
- "is all configurations.",
- &configs)
+ "Comma separated list of configurations to include. The default\n"
+ "is all configurations.",
+ &configs)
.OptionalFlag("--preferred-density",
"Selects the closest matching density and strips out all others.",
&preferred_density)
@@ -1841,6 +1855,10 @@
.OptionalFlagList("--add-javadoc-annotation",
"Adds a JavaDoc annotation to all generated Java classes.",
&options.javadoc_annotations)
+ .OptionalFlag("--output-text-symbols",
+ "Generates a text file containing the resource symbols of the R class in\n"
+ "the specified folder.",
+ &options.generate_text_symbols_path)
.OptionalSwitch("--auto-add-overlay",
"Allows the addition of new resources in overlays without\n"
"<add-resource> tags.",
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index 68bdb95..a8226c0 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -22,6 +22,7 @@
#include <sstream>
#include <tuple>
+#include "android-base/errors.h"
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "androidfw/StringPiece.h"
@@ -227,7 +228,8 @@
const Styleable& styleable,
const StringPiece& package_name_to_generate,
ClassDefinition* out_class_def,
- MethodDefinition* out_rewrite_method) {
+ MethodDefinition* out_rewrite_method,
+ std::ostream* out_r_txt) {
const std::string array_field_name = TransformToFieldName(name.entry);
std::unique_ptr<ResourceArrayMember> array_def =
util::make_unique<ResourceArrayMember>(array_field_name);
@@ -328,10 +330,25 @@
array_def->GetCommentBuilder()->AppendComment(styleable_comment.str());
}
+ if (out_r_txt != nullptr) {
+ *out_r_txt << "int[] styleable " << array_field_name << " {";
+ }
+
// Add the ResourceIds to the array member.
- for (const StyleableAttr& styleable_attr : sorted_attributes) {
- const ResourceId id = styleable_attr.attr_ref->id.value_or_default(ResourceId(0));
+ for (size_t i = 0; i < attr_count; i++) {
+ const ResourceId id = sorted_attributes[i].attr_ref->id.value_or_default(ResourceId(0));
array_def->AddElement(id);
+
+ if (out_r_txt != nullptr) {
+ if (i != 0) {
+ *out_r_txt << ",";
+ }
+ *out_r_txt << " " << id;
+ }
+ }
+
+ if (out_r_txt != nullptr) {
+ *out_r_txt << " }\n";
}
// Add the Styleable array to the Styleable class.
@@ -386,6 +403,11 @@
attr_processor->AppendComment(
StringPrintf("@attr name %s:%s", package_name.data(), attr_name.entry.data()));
+ if (out_r_txt != nullptr) {
+ *out_r_txt << StringPrintf("int styleable %s %d\n", sorted_attributes[i].field_name.data(),
+ (int)i);
+ }
+
out_class_def->AddMember(std::move(index_member));
}
@@ -406,7 +428,8 @@
void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const ResourceId& id,
const ResourceEntry& entry, ClassDefinition* out_class_def,
- MethodDefinition* out_rewrite_method) {
+ MethodDefinition* out_rewrite_method,
+ std::ostream* out_r_txt) {
const std::string field_name = TransformToFieldName(name.entry);
std::unique_ptr<ResourceMember> resource_member =
util::make_unique<ResourceMember>(field_name, id);
@@ -434,6 +457,10 @@
out_class_def->AddMember(std::move(resource_member));
+ if (out_r_txt != nullptr) {
+ *out_r_txt << "int " << name.type << " " << field_name << " " << id << "\n";
+ }
+
if (out_rewrite_method != nullptr) {
const StringPiece& type_str = ToString(name.type);
out_rewrite_method->AppendStatement(StringPrintf("%s.%s = (%s.%s & 0x00ffffff) | (p << 24);",
@@ -470,7 +497,8 @@
const ResourceTablePackage& package,
const ResourceTableType& type,
ClassDefinition* out_type_class_def,
- MethodDefinition* out_rewrite_method_def) {
+ MethodDefinition* out_rewrite_method_def,
+ std::ostream* out_r_txt) {
for (const auto& entry : type.entries) {
const Maybe<std::string> unmangled_name =
UnmangleResource(package.name, package_name_to_generate, *entry);
@@ -505,15 +533,17 @@
static_cast<const Styleable*>(entry->values.front()->value.get());
ProcessStyleable(resource_name, id, *styleable, package_name_to_generate, out_type_class_def,
- out_rewrite_method_def);
+ out_rewrite_method_def, out_r_txt);
} else {
- ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def);
+ ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def,
+ out_r_txt);
}
}
return true;
}
-bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::ostream* out) {
+bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::ostream* out,
+ std::ostream* out_r_txt) {
return Generate(package_name_to_generate, package_name_to_generate, out);
}
@@ -527,8 +557,8 @@
}
bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
- const StringPiece& out_package_name,
- std::ostream* out) {
+ const StringPiece& out_package_name, std::ostream* out,
+ std::ostream* out_r_txt) {
ClassDefinition r_class("R", ClassQualifier::kNone, true);
std::unique_ptr<MethodDefinition> rewrite_method;
@@ -558,7 +588,7 @@
std::unique_ptr<ClassDefinition> class_def = util::make_unique<ClassDefinition>(
ToString(type->type), ClassQualifier::kStatic, force_creation_if_empty);
if (!ProcessType(package_name_to_generate, *package, *type, class_def.get(),
- rewrite_method.get())) {
+ rewrite_method.get(), out_r_txt)) {
return false;
}
@@ -567,7 +597,7 @@
const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate);
if (priv_type) {
if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(),
- rewrite_method.get())) {
+ rewrite_method.get(), out_r_txt)) {
return false;
}
}
@@ -597,6 +627,16 @@
}
out->flush();
+
+ if (out_r_txt != nullptr) {
+ out_r_txt->flush();
+
+ if (!*out_r_txt) {
+ error_ = android::base::SystemErrorCodeToString(errno);
+ return false;
+ }
+ }
+
return true;
}
diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h
index 4510430..18746ff 100644
--- a/tools/aapt2/java/JavaClassGenerator.h
+++ b/tools/aapt2/java/JavaClassGenerator.h
@@ -59,7 +59,7 @@
std::vector<std::string> javadoc_annotations;
};
-// Generates the R.java file for a resource table.
+// Generates the R.java file for a resource table and optionally an R.txt file.
class JavaClassGenerator {
public:
JavaClassGenerator(IAaptContext* context, ResourceTable* table,
@@ -69,10 +69,12 @@
// All symbols technically belong to a single package, but linked libraries will
// have their names mangled, denoting that they came from a different package.
// We need to generate these symbols in a separate file. Returns true on success.
- bool Generate(const android::StringPiece& package_name_to_generate, std::ostream* out);
+ bool Generate(const android::StringPiece& package_name_to_generate, std::ostream* out,
+ std::ostream* out_r_txt = nullptr);
bool Generate(const android::StringPiece& package_name_to_generate,
- const android::StringPiece& output_package_name, std::ostream* out);
+ const android::StringPiece& output_package_name, std::ostream* out,
+ std::ostream* out_r_txt = nullptr);
const std::string& getError() const;
@@ -88,13 +90,14 @@
bool ProcessType(const android::StringPiece& package_name_to_generate,
const ResourceTablePackage& package, const ResourceTableType& type,
- ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def);
+ ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def,
+ std::ostream* out_r_txt);
// Writes a resource to the R.java file, optionally writing out a rewrite rule for its package
// ID if `out_rewrite_method` is not nullptr.
void ProcessResource(const ResourceNameRef& name, const ResourceId& id,
const ResourceEntry& entry, ClassDefinition* out_class_def,
- MethodDefinition* out_rewrite_method);
+ MethodDefinition* out_rewrite_method, std::ostream* out_r_txt);
// Writes a styleable resource to the R.java file, optionally writing out a rewrite rule for
// its package ID if `out_rewrite_method` is not nullptr.
@@ -102,7 +105,8 @@
void ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
const Styleable& styleable,
const android::StringPiece& package_name_to_generate,
- ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method);
+ ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method,
+ std::ostream* out_r_txt);
IAaptContext* context_;
ResourceTable* table_;
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index a21fe68..78b6f71 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -45,7 +45,7 @@
import java.util.Scanner;
import java.util.Set;
-import static android.graphics.Typeface.Builder.RESOLVE_BY_FONT_TABLE;
+import static android.graphics.Typeface.RESOLVE_BY_FONT_TABLE;
import static android.graphics.Typeface_Delegate.SYSTEM_FONTS;
/**