Merge "Add new facility to find out when a PendingIntent is canceled." into oc-dev
diff --git a/api/current.txt b/api/current.txt
index 2761687..902f168 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
@@ -991,6 +993,7 @@
field public static final int persistableMode = 16843821; // 0x101042d
field public static final int persistent = 16842765; // 0x101000d
field public static final int persistentDrawingCache = 16842990; // 0x10100ee
+ field public static final int persistentFeature = 16844134; // 0x1010566
field public static final deprecated int phoneNumber = 16843111; // 0x1010167
field public static final int pivotX = 16843189; // 0x10101b5
field public static final int pivotY = 16843190; // 0x10101b6
@@ -1269,7 +1272,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
@@ -9346,6 +9348,7 @@
field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
+ field public static final java.lang.String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED";
field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED";
field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
@@ -13760,7 +13763,7 @@
}
public class Typeface {
- method public static void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
+ method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
method public static android.graphics.Typeface create(java.lang.String, int);
method public static android.graphics.Typeface create(android.graphics.Typeface, int);
method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String);
@@ -13787,6 +13790,7 @@
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 android.graphics.Typeface.Builder setFallback(java.lang.String);
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(boolean);
@@ -13794,7 +13798,7 @@
method public android.graphics.Typeface.Builder setWeight(int);
}
- public static abstract interface Typeface.FontRequestCallback {
+ public static abstract deprecated interface Typeface.FontRequestCallback {
method public abstract void onTypefaceRequestFailed(int);
method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
@@ -13826,7 +13830,7 @@
public class AdaptiveIconDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
method public void draw(android.graphics.Canvas);
method public android.graphics.drawable.Drawable getBackground();
- method public static float getExtraInsetPercentage();
+ method public static float getExtraInsetFraction();
method public android.graphics.drawable.Drawable getForeground();
method public android.graphics.Path getIconMask();
method public int getOpacity();
@@ -20581,7 +20585,7 @@
method public double getAccumulatedDeltaRangeMeters();
method public int getAccumulatedDeltaRangeState();
method public double getAccumulatedDeltaRangeUncertaintyMeters();
- method public double getAutomaticGainControlLevelInDb();
+ method public double getAutomaticGainControlLevelDb();
method public long getCarrierCycles();
method public float getCarrierFrequencyHz();
method public double getCarrierPhase();
@@ -20597,7 +20601,7 @@
method public int getState();
method public int getSvid();
method public double getTimeOffsetNanos();
- method public boolean hasAutomaticGainControlLevelInDb();
+ method public boolean hasAutomaticGainControlLevelDb();
method public boolean hasCarrierCycles();
method public boolean hasCarrierFrequencyHz();
method public boolean hasCarrierPhase();
@@ -20691,7 +20695,7 @@
method public int getSatelliteCount();
method public int getSvid(int);
method public boolean hasAlmanacData(int);
- method public boolean hasCarrierFrequency(int);
+ method public boolean hasCarrierFrequencyHz(int);
method public boolean hasEphemerisData(int);
method public boolean usedInFix(int);
field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
@@ -21809,24 +21813,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 {
@@ -21838,6 +21837,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 {
}
@@ -22281,12 +22287,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 {
@@ -22424,6 +22430,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();
@@ -22455,6 +22462,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);
@@ -34492,6 +34504,10 @@
}
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;
+ method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler);
}
public static final class FontsContract.Columns implements android.provider.BaseColumns {
@@ -34508,6 +34524,35 @@
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 static class FontsContract.FontRequestCallback {
+ ctor public FontsContract.FontRequestCallback();
+ method public void onTypefaceRequestFailed(int);
+ method public void onTypefaceRetrieved(android.graphics.Typeface);
+ field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+ field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+ field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+ field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+ field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+ field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
+ }
+
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";
@@ -40120,7 +40165,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();
@@ -45342,6 +45388,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();
@@ -45660,6 +45707,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);
diff --git a/api/system-current.txt b/api/system-current.txt
index d5e772e..9ed5338 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
@@ -1107,6 +1109,7 @@
field public static final int persistableMode = 16843821; // 0x101042d
field public static final int persistent = 16842765; // 0x101000d
field public static final int persistentDrawingCache = 16842990; // 0x10100ee
+ field public static final int persistentFeature = 16844134; // 0x1010566
field public static final deprecated int phoneNumber = 16843111; // 0x1010167
field public static final int pivotX = 16843189; // 0x10101b5
field public static final int pivotY = 16843190; // 0x10101b6
@@ -1389,7 +1392,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
@@ -9872,6 +9874,7 @@
field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
+ field public static final java.lang.String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED";
field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED";
field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
@@ -14527,7 +14530,7 @@
}
public class Typeface {
- method public static void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
+ method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
method public static android.graphics.Typeface create(java.lang.String, int);
method public static android.graphics.Typeface create(android.graphics.Typeface, int);
method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String);
@@ -14554,6 +14557,7 @@
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 android.graphics.Typeface.Builder setFallback(java.lang.String);
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(boolean);
@@ -14561,7 +14565,7 @@
method public android.graphics.Typeface.Builder setWeight(int);
}
- public static abstract interface Typeface.FontRequestCallback {
+ public static abstract deprecated interface Typeface.FontRequestCallback {
method public abstract void onTypefaceRequestFailed(int);
method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
@@ -14593,7 +14597,7 @@
public class AdaptiveIconDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
method public void draw(android.graphics.Canvas);
method public android.graphics.drawable.Drawable getBackground();
- method public static float getExtraInsetPercentage();
+ method public static float getExtraInsetFraction();
method public android.graphics.drawable.Drawable getForeground();
method public android.graphics.Path getIconMask();
method public int getOpacity();
@@ -22081,7 +22085,7 @@
method public double getAccumulatedDeltaRangeMeters();
method public int getAccumulatedDeltaRangeState();
method public double getAccumulatedDeltaRangeUncertaintyMeters();
- method public double getAutomaticGainControlLevelInDb();
+ method public double getAutomaticGainControlLevelDb();
method public long getCarrierCycles();
method public float getCarrierFrequencyHz();
method public double getCarrierPhase();
@@ -22097,7 +22101,7 @@
method public int getState();
method public int getSvid();
method public double getTimeOffsetNanos();
- method public boolean hasAutomaticGainControlLevelInDb();
+ method public boolean hasAutomaticGainControlLevelDb();
method public boolean hasCarrierCycles();
method public boolean hasCarrierFrequencyHz();
method public boolean hasCarrierPhase();
@@ -22191,7 +22195,7 @@
method public int getSatelliteCount();
method public int getSvid(int);
method public boolean hasAlmanacData(int);
- method public boolean hasCarrierFrequency(int);
+ method public boolean hasCarrierFrequencyHz(int);
method public boolean hasEphemerisData(int);
method public boolean usedInFix(int);
field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
@@ -23638,24 +23642,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 {
@@ -23667,6 +23666,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 {
}
@@ -24110,12 +24116,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 {
@@ -24253,6 +24259,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();
@@ -24284,6 +24291,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);
@@ -37469,6 +37481,10 @@
}
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;
+ method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler);
}
public static final class FontsContract.Columns implements android.provider.BaseColumns {
@@ -37485,6 +37501,35 @@
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 static class FontsContract.FontRequestCallback {
+ ctor public FontsContract.FontRequestCallback();
+ method public void onTypefaceRequestFailed(int);
+ method public void onTypefaceRetrieved(android.graphics.Typeface);
+ field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+ field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+ field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+ field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+ field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+ field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
+ }
+
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";
@@ -43620,7 +43665,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();
@@ -48899,6 +48945,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();
@@ -49217,6 +49264,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);
diff --git a/api/test-current.txt b/api/test-current.txt
index 5c3a461..29d4080 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
@@ -991,6 +993,7 @@
field public static final int persistableMode = 16843821; // 0x101042d
field public static final int persistent = 16842765; // 0x101000d
field public static final int persistentDrawingCache = 16842990; // 0x10100ee
+ field public static final int persistentFeature = 16844134; // 0x1010566
field public static final deprecated int phoneNumber = 16843111; // 0x1010167
field public static final int pivotX = 16843189; // 0x10101b5
field public static final int pivotY = 16843190; // 0x10101b6
@@ -1269,7 +1272,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
@@ -9380,6 +9382,7 @@
field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
+ field public static final java.lang.String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED";
field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED";
field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
@@ -11779,15 +11782,6 @@
field protected final java.util.ArrayList<T> mObservers;
}
- public final class PageViewCursor extends android.database.CursorWrapper implements android.database.CrossProcessCursor {
- ctor public PageViewCursor(android.database.Cursor, android.os.Bundle);
- method public void fillWindow(int, android.database.CursorWindow);
- method public android.database.CursorWindow getWindow();
- method public boolean onMove(int, int);
- method public static android.database.Cursor wrap(android.database.Cursor, android.os.Bundle);
- field public static final java.lang.String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED";
- }
-
public class SQLException extends java.lang.RuntimeException {
ctor public SQLException();
ctor public SQLException(java.lang.String);
@@ -13811,7 +13805,7 @@
}
public class Typeface {
- method public static void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
+ method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
method public static android.graphics.Typeface create(java.lang.String, int);
method public static android.graphics.Typeface create(android.graphics.Typeface, int);
method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String);
@@ -13838,6 +13832,7 @@
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 android.graphics.Typeface.Builder setFallback(java.lang.String);
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(boolean);
@@ -13845,7 +13840,7 @@
method public android.graphics.Typeface.Builder setWeight(int);
}
- public static abstract interface Typeface.FontRequestCallback {
+ public static abstract deprecated interface Typeface.FontRequestCallback {
method public abstract void onTypefaceRequestFailed(int);
method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
@@ -13877,7 +13872,7 @@
public class AdaptiveIconDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
method public void draw(android.graphics.Canvas);
method public android.graphics.drawable.Drawable getBackground();
- method public static float getExtraInsetPercentage();
+ method public static float getExtraInsetFraction();
method public android.graphics.drawable.Drawable getForeground();
method public android.graphics.Path getIconMask();
method public int getOpacity();
@@ -14029,6 +14024,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();
@@ -14357,6 +14353,7 @@
method public void setPadding(android.graphics.Rect);
method public void setShaderFactory(android.graphics.drawable.ShapeDrawable.ShaderFactory);
method public void setShape(android.graphics.drawable.shapes.Shape);
+ method public void setXfermode(android.graphics.Xfermode);
}
public static abstract class ShapeDrawable.ShaderFactory {
@@ -20657,7 +20654,7 @@
method public double getAccumulatedDeltaRangeMeters();
method public int getAccumulatedDeltaRangeState();
method public double getAccumulatedDeltaRangeUncertaintyMeters();
- method public double getAutomaticGainControlLevelInDb();
+ method public double getAutomaticGainControlLevelDb();
method public long getCarrierCycles();
method public float getCarrierFrequencyHz();
method public double getCarrierPhase();
@@ -20673,7 +20670,7 @@
method public int getState();
method public int getSvid();
method public double getTimeOffsetNanos();
- method public boolean hasAutomaticGainControlLevelInDb();
+ method public boolean hasAutomaticGainControlLevelDb();
method public boolean hasCarrierCycles();
method public boolean hasCarrierFrequencyHz();
method public boolean hasCarrierPhase();
@@ -20804,7 +20801,7 @@
method public int getSatelliteCount();
method public int getSvid(int);
method public boolean hasAlmanacData(int);
- method public boolean hasCarrierFrequency(int);
+ method public boolean hasCarrierFrequencyHz(int);
method public boolean hasEphemerisData(int);
method public boolean usedInFix(int);
field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
@@ -21923,24 +21920,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 {
@@ -21952,6 +21944,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 {
}
@@ -22395,12 +22394,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 {
@@ -22538,6 +22537,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();
@@ -22569,6 +22569,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);
@@ -34634,6 +34639,10 @@
}
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;
+ method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler);
}
public static final class FontsContract.Columns implements android.provider.BaseColumns {
@@ -34650,6 +34659,35 @@
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 static class FontsContract.FontRequestCallback {
+ ctor public FontsContract.FontRequestCallback();
+ method public void onTypefaceRequestFailed(int);
+ method public void onTypefaceRetrieved(android.graphics.Typeface);
+ field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+ field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+ field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+ field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+ field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+ field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
+ }
+
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";
@@ -40321,7 +40359,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();
@@ -45714,6 +45753,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();
@@ -46036,6 +46076,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);
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/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/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/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 92216d1..e50bc13 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -26,6 +26,7 @@
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.text.TextUtils;
@@ -139,7 +140,7 @@
private int mImportance = DEFAULT_IMPORTANCE;
private boolean mBypassDnd;
private int mLockscreenVisibility = DEFAULT_VISIBILITY;
- private Uri mSound;
+ private Uri mSound = Settings.System.DEFAULT_NOTIFICATION_URI;
private boolean mLights;
private int mLightColor = DEFAULT_LIGHT_COLOR;
private long[] mVibration;
@@ -330,7 +331,8 @@
/**
* Sets the sound that should be played for notifications posted to this channel and its
- * audio attributes.
+ * audio attributes. Notification channels with an {@link #getImportance() importance} of at
+ * least {@link NotificationManager#IMPORTANCE_DEFAULT} should have a sound.
*
* Only modifiable before the channel is submitted to
* {@link NotificationManager#notify(String, int, Notification)}.
@@ -445,7 +447,7 @@
}
/**
- * Returns the user specified importance {e.g. @link NotificationManager#IMPORTANCE_LOW} for
+ * Returns the user specified importance e.g. {@link NotificationManager#IMPORTANCE_LOW} for
* notifications posted to this channel.
*/
public int getImportance() {
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 28421eb..8519dba 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -1011,6 +1011,18 @@
}
/**
+ * check if in-band ringing is supported for this platform.
+ *
+ * @return true if in-band ringing is supported
+ * false if in-band ringing is not supported
+ * @hide
+ */
+ public static boolean isInbandRingingSupported(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_bluetooth_hfp_inband_ringing_support);
+ }
+
+ /**
* Send Headset the BIND response from AG to report change in the status of the
* HF indicators to the headset
*
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 2f87633..d428a3a 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -24,7 +24,6 @@
import android.database.CursorToBulkCursorAdaptor;
import android.database.DatabaseUtils;
import android.database.IContentObserver;
-import android.database.PageViewCursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -104,7 +103,6 @@
if (cursor != null) {
CursorToBulkCursorAdaptor adaptor = null;
- cursor = PageViewCursor.wrap(cursor, queryArgs);
try {
adaptor = new CursorToBulkCursorAdaptor(cursor, observer,
getProviderName());
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 88bade1..6375775 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2745,7 +2745,8 @@
* {@link #BIND_WAIVE_PRIORITY}.
* @return If you have successfully bound to the service, {@code true} is returned;
* {@code false} is returned if the connection is not made so you will not
- * receive the service object.
+ * receive the service object. However, you should still call
+ * {@link #unbindService} to release the connection.
*
* @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a4b5ffd..52a8760 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2062,13 +2062,13 @@
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
/**
- * Broadcast Action: A new application package has been installed on the
+ * Broadcast Action: An application package has been installed or updated on the
* device. The data contains the name of the package. Note that the
* newly installed package does <em>not</em> receive this broadcast.
* <p>May include the following extras:
* <ul>
- * <li> {@link #EXTRA_UID} containing the integer uid assigned to the new package.
- * <li> {@link #EXTRA_REPLACING} is set to true if this is following
+ * <li> {@link #EXTRA_UID} containing the integer uid assigned to this package.
+ * <li> {@link #EXTRA_REPLACING} is set to {@code true} if this is following
* an {@link #ACTION_PACKAGE_REMOVED} broadcast for the same package.
* </ul>
*
@@ -2078,6 +2078,22 @@
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
/**
+ * Broadcast Action: A new application package has been installed on the
+ * device. The data contains the name of the package. Note that the
+ * newly installed package does <em>not</em> receive this broadcast.
+ * <p class="note">Unlike {@link #ACTION_PACKAGE_ADDED}, this broadcast is delivered
+ * to manifest receivers as well as those registered at runtime.
+ * <p>May include the following extras:
+ * <ul>
+ * <li> {@link #EXTRA_UID} containing the integer uid assigned to the new package.
+ * </ul>
+ *
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PACKAGE_FIRST_ADDED = "android.intent.action.PACKAGE_FIRST_ADDED";
+ /**
* Broadcast Action: A new version of an application package has been
* installed, replacing an existing version that was previously installed.
* The data contains the name of the package.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c7a0da5..e5c8f0d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1763,6 +1763,17 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports any
+ * one of the {@link #FEATURE_NFC}, {@link #FEATURE_NFC_HOST_CARD_EMULATION},
+ * or {@link #FEATURE_NFC_HOST_CARD_EMULATION_NFCF} features.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_NFC_ANY = "android.hardware.nfc.any";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports the OpenGL ES
* <a href="http://www.khronos.org/registry/gles/extensions/ANDROID/ANDROID_extension_pack_es31a.txt">
* Android Extension Pack</a>.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e64b2a5..11c658a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3363,7 +3363,12 @@
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_persistent,
false)) {
- ai.flags |= ApplicationInfo.FLAG_PERSISTENT;
+ // Check if persistence is based on a feature being present
+ final String requiredFeature = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestApplication_persistentFeature);
+ if (requiredFeature == null || mCallback.hasFeature(requiredFeature)) {
+ ai.flags |= ApplicationInfo.FLAG_PERSISTENT;
+ }
}
}
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/database/PageViewCursor.java b/core/java/android/database/PageViewCursor.java
deleted file mode 100644
index 4569a27..0000000
--- a/core/java/android/database/PageViewCursor.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.database;
-
-import static com.android.internal.util.ArrayUtils.contains;
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.annotation.Nullable;
-import android.annotation.TestApi;
-import android.content.ContentResolver;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.Log;
-import android.util.MathUtils;
-
-import java.util.Arrays;
-
-/**
- * Cursor wrapper that provides visibility into a subset of a wrapped cursor.
- *
- * The window is specified by offset and limit.
- *
- * @hide
- */
-@TestApi
-public final class PageViewCursor extends CursorWrapper implements CrossProcessCursor {
-
- /** An extra added to results that are auto-paged using the wrapper. */
- public static final String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED";
-
- private static final String[] EMPTY_ARGS = new String[0];
- private static final String TAG = "PageViewCursor";
- private static final boolean DEBUG = Build.IS_DEBUGGABLE;
- private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
-
- private final int mOffset; // aka first index
- private final int mCount;
- private final Bundle mExtras;
-
- private @Nullable CursorWindow mWindow;
- private int mPos = -1;
- private int mWindowFillCount = 0;
-
- /**
- * @see PageViewCursor#wrap(Cursor, Bundle)
- */
- public PageViewCursor(Cursor cursor, Bundle queryArgs) {
- super(cursor);
-
- int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
- int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MAX_VALUE);
-
- checkArgument(offset > -1);
- checkArgument(limit > -1);
-
- int count = mCursor.getCount();
-
- mOffset = offset;
-
- mExtras = new Bundle();
- Bundle extras = cursor.getExtras();
- if (extras != null) {
- mExtras.putAll(extras);
- }
-
- // When we're wrapping another cursor, it should not already be "paged".
- checkArgument(!hasPagedResponseDetails(mExtras));
-
- mExtras.putBoolean(EXTRA_AUTO_PAGED, true);
- mExtras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, count);
-
- // Ensure we retain any extra args supplied in cursor extras, and add
- // offset and/or limit.
- String[] existingArgs = mExtras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- existingArgs = existingArgs != null ? existingArgs : EMPTY_ARGS;
-
- int size = existingArgs.length;
-
- // copy the array with space for the extra query args we'll be adding.
- String[] newArgs = Arrays.copyOf(existingArgs, size + 2);
-
- if (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)) {
- newArgs[size++] = ContentResolver.QUERY_ARG_OFFSET;
- }
- if (queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT)) {
- newArgs[size++] = ContentResolver.QUERY_ARG_LIMIT;
- }
-
- assert(size > existingArgs.length); // must add at least one arg.
-
- // At this point there may be a null element at the end of
- // the array because our pre-sizing didn't match the actualy
- // number of args we added. So we trim.
- if (size == newArgs.length - 1) {
- newArgs = Arrays.copyOf(newArgs, size);
- }
- mExtras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, newArgs);
-
- mCount = MathUtils.constrain(count - offset, 0, limit);
-
- if (DEBUG) Log.d(TAG, "Wrapped cursor"
- + " offset: " + mOffset
- + ", limit: " + limit
- + ", delegate_size: " + count
- + ", paged_count: " + mCount);
- }
-
- @Override
- public Bundle getExtras() {
- return mExtras;
- }
-
- @Override
- public int getPosition() {
- return mPos;
- }
-
- @Override
- public boolean isBeforeFirst() {
- if (mCount == 0) {
- return true;
- }
- return mPos == -1;
- }
-
- @Override
- public boolean isAfterLast() {
- if (mCount == 0) {
- return true;
- }
- return mPos == mCount;
- }
-
- @Override
- public boolean isFirst() {
- return mPos == 0;
- }
-
- @Override
- public boolean isLast() {
- return mPos == mCount - 1;
- }
-
- @Override
- public boolean moveToFirst() {
- return moveToPosition(0);
- }
-
- @Override
- public boolean moveToLast() {
- return moveToPosition(mCount - 1);
- }
-
- @Override
- public boolean moveToNext() {
- return move(1);
- }
-
- @Override
- public boolean moveToPrevious() {
- return move(-1);
- }
-
- @Override
- public boolean move(int offset) {
- return moveToPosition(mPos + offset);
- }
-
- @Override
- public boolean moveToPosition(int position) {
- if (position >= mCount) {
- if (VERBOSE) Log.v(TAG, "Invalid Positon: " + position + " >= count: " + mCount
- + ". Moving to last record.");
- mPos = mCount;
- super.moveToPosition(mOffset + mPos); // move into "after last" state.
- return false;
- }
-
- // Make sure position isn't before the beginning of the cursor
- if (position < 0) {
- if (VERBOSE) Log.v(TAG, "Ignoring invalid move to position: " + position);
- mPos = -1;
- super.moveToPosition(mPos);
- return false;
- }
-
- if (position == mPos) {
- if (VERBOSE) Log.v(TAG, "Ignoring no-op move to position: " + position);
- return true;
- }
-
- int delegatePosition = position + mOffset;
- if (VERBOSE) Log.v(TAG, "Moving delegate cursor to position: " + delegatePosition);
- if (super.moveToPosition(delegatePosition)) {
- mPos = position;
- return true;
- } else {
- mPos = -1;
- super.moveToPosition(-1);
- return false;
- }
- }
-
- @Override
- public boolean onMove(int oldPosition, int newPosition) {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public int getCount() {
- return mCount;
- }
-
- @Override
- public boolean getWantsAllOnMoveCalls() {
- return false; // we want bulk cursor adapter to lift data into a CursorWindow.
- }
-
- @Override
- public CursorWindow getWindow() {
- assert(mPos == -1 || mPos == 0);
- if (mWindow == null) {
- mWindow = new CursorWindow("PageViewCursorWindow");
- fillWindow(0, mWindow);
- }
-
- return mWindow;
- }
-
- @Override
- public void fillWindow(int position, CursorWindow window) {
- assert(window == mWindow);
-
- if (mWindowFillCount++ > 0) {
- Log.w(TAG, "Re-filling window on paged cursor! Reduce ContentResolver.QUERY_ARG_LIMIT");
- }
-
- DatabaseUtils.cursorFillWindow(this, position, window);
- }
-
- /**
- * Wraps the cursor such that it will honor paging args (if present), AND if the cursor does
- * not report paging size.
- * <p>
- * No-op if cursor already contains paging or is less than specified page size.
- */
- public static Cursor wrap(Cursor cursor, @Nullable Bundle queryArgs) {
-
- boolean hasPagingArgs = queryArgs != null
- && (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)
- || queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT));
-
- if (!hasPagingArgs) {
- if (VERBOSE) Log.v(TAG, "No-wrap: No paging args in request.");
- return cursor;
- }
-
- if (hasPagedResponseDetails(cursor.getExtras())) {
- if (VERBOSE) Log.v(TAG, "No-wrap. Cursor has paging details.");
- return cursor;
- }
-
- // Cursors that want all calls aren't compatible with our way
- // of doing business. TODO: Cover this case in CTS.
- if (cursor.getWantsAllOnMoveCalls()) {
- Log.w(TAG, "Unable to wrap cursor that wants to hear about move calls.");
- return cursor;
- }
-
- return new PageViewCursor(cursor, queryArgs);
- }
-
- /**
- * @return true if the extras contains information indicating the associated cursor is
- * paged.
- */
- private static boolean hasPagedResponseDetails(@Nullable Bundle extras) {
- if (extras == null) {
- return false;
- }
-
- if (extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)) {
- return true;
- }
-
- String[] honoredArgs = extras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- if (honoredArgs != null
- && (contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)
- || contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT))) {
- return true;
- }
-
- return false;
- }
-}
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 425a89d..1e98301 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -37,7 +37,7 @@
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about communicating with USB hardware, read the
- * <a href="{@docRoot}guide/topics/usb/index.html">USB</a> developer guide.</p>
+ * <a href="{@docRoot}guide/topics/connectivity/usb/index.html">USB</a> developer guide.</p>
* </div>
*/
public class UsbDevice implements Parcelable {
diff --git a/core/java/android/metrics/MetricsReader.java b/core/java/android/metrics/MetricsReader.java
index d8768e7..5be977a 100644
--- a/core/java/android/metrics/MetricsReader.java
+++ b/core/java/android/metrics/MetricsReader.java
@@ -27,6 +27,7 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.Queue;
+import java.util.concurrent.TimeUnit;
/**
* Read platform logs.
@@ -80,7 +81,7 @@
mPendingQueue.clear();
mSeenQueue.clear();
for (Event event : nativeEvents) {
- final long eventTimestampMs = event.getTimeNanos() / 1000000;
+ final long eventTimestampMs = event.getTimeMillis();
Object data = event.getData();
Object[] objects;
if (data instanceof Object[]) {
@@ -152,24 +153,25 @@
*/
@VisibleForTesting
public static class Event {
- long mTimeNanos;
+ long mTimeMillis;
int mPid;
Object mData;
- public Event(long timeNanos, int pid, Object data) {
- mTimeNanos = timeNanos;
+ public Event(long timeMillis, int pid, Object data) {
+ mTimeMillis = timeMillis;
mPid = pid;
mData = data;
}
Event(EventLog.Event nativeEvent) {
- mTimeNanos = nativeEvent.getTimeNanos();
+ mTimeMillis = TimeUnit.MILLISECONDS.convert(
+ nativeEvent.getTimeNanos(), TimeUnit.NANOSECONDS);
mPid = nativeEvent.getProcessId();
mData = nativeEvent.getData();
}
- public long getTimeNanos() {
- return mTimeNanos;
+ public long getTimeMillis() {
+ return mTimeMillis;
}
public int getProcessId() {
@@ -196,7 +198,8 @@
throws IOException {
// Testing in Android: the Static Final Class Strikes Back!
ArrayList<EventLog.Event> nativeEvents = new ArrayList<>();
- EventLog.readEventsOnWrapping(tags, horizonMs, nativeEvents);
+ long horizonNs = TimeUnit.NANOSECONDS.convert(horizonMs, TimeUnit.MILLISECONDS);
+ EventLog.readEventsOnWrapping(tags, horizonNs, nativeEvents);
for (EventLog.Event nativeEvent : nativeEvents) {
Event event = new Event(nativeEvent);
events.add(event);
diff --git a/core/java/android/os/ProxyFileDescriptorCallback.java b/core/java/android/os/ProxyFileDescriptorCallback.java
index 2e9f8d9..e69fb55 100644
--- a/core/java/android/os/ProxyFileDescriptorCallback.java
+++ b/core/java/android/os/ProxyFileDescriptorCallback.java
@@ -21,12 +21,14 @@
/**
* Callback that handles file system requests from ProxyFileDescriptor.
+ *
+ * @see android.os.storage.StorageManager#openProxyFileDescriptor(int, ProxyFileDescriptorCallback)
*/
public abstract class ProxyFileDescriptorCallback {
/**
* Returns size of bytes provided by the file descriptor.
- * @return Size of bytes
- * @throws ErrnoException
+ * @return Size of bytes.
+ * @throws ErrnoException ErrnoException containing E constants in OsConstants.
*/
public long onGetSize() throws ErrnoException {
throw new ErrnoException("onGetSize", OsConstants.EBADF);
@@ -35,11 +37,13 @@
/**
* Provides bytes read from file descriptor.
* It needs to return exact requested size of bytes unless it reaches file end.
- * @param offset Where to read bytes from.
+ * @param offset Offset in bytes from the file head specifying where to read bytes. If a seek
+ * operation is conducted on the file descriptor, then a read operation is requested, the
+ * offset refrects the proper position of requested bytes.
* @param size Size for read bytes.
* @param data Byte array to store read bytes.
* @return Size of bytes returned by the function.
- * @throws ErrnoException
+ * @throws ErrnoException ErrnoException containing E constants in OsConstants.
*/
public int onRead(long offset, int size, byte[] data) throws ErrnoException {
throw new ErrnoException("onRead", OsConstants.EBADF);
@@ -47,19 +51,23 @@
/**
* Handles bytes written to file descriptor.
- * @param offset Where to write bytes to.
+ * @param offset Offset in bytes from the file head specifying where to write bytes. If a seek
+ * operation is conducted on the file descriptor, then a write operation is requested, the
+ * offset refrects the proper position of requested bytes.
* @param size Size for write bytes.
* @param data Byte array to be written to somewhere.
* @return Size of bytes processed by the function.
- * @throws ErrnoException
+ * @throws ErrnoException ErrnoException containing E constants in OsConstants.
*/
public int onWrite(long offset, int size, byte[] data) throws ErrnoException {
throw new ErrnoException("onWrite", OsConstants.EBADF);
}
/**
- * Processes fsync request.
- * @throws ErrnoException
+ * Ensures all the written data are stored in permanent storage device.
+ * For example, if it has data stored in on memory cache, it needs to flush data to storage
+ * device.
+ * @throws ErrnoException ErrnoException containing E constants in OsConstants.
*/
public void onFsync() throws ErrnoException {
throw new ErrnoException("onFsync", OsConstants.EINVAL);
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 f2aed5d..e9ef770 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.
@@ -140,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 */
@@ -165,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
@@ -196,33 +330,350 @@
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);
}
}
+ /**
+ * Interface used to receive asynchronously fetched typefaces.
+ */
+ public static class FontRequestCallback {
+ /**
+ * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
+ * provider was not found on the device.
+ */
+ public static final int FAIL_REASON_PROVIDER_NOT_FOUND = RESULT_CODE_PROVIDER_NOT_FOUND;
+ /**
+ * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
+ * provider must be authenticated and the given certificates do not match its signature.
+ */
+ public static final int FAIL_REASON_WRONG_CERTIFICATES = RESULT_CODE_WRONG_CERTIFICATES;
+ /**
+ * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
+ * returned by the provider was not loaded properly.
+ */
+ public static final int FAIL_REASON_FONT_LOAD_ERROR = -3;
+ /**
+ * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
+ * provider did not return any results for the given query.
+ */
+ public static final int FAIL_REASON_FONT_NOT_FOUND = Columns.RESULT_CODE_FONT_NOT_FOUND;
+ /**
+ * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
+ * provider found the queried font, but it is currently unavailable.
+ */
+ public static final int FAIL_REASON_FONT_UNAVAILABLE = Columns.RESULT_CODE_FONT_UNAVAILABLE;
+ /**
+ * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
+ * query was not supported by the provider.
+ */
+ public static final int FAIL_REASON_MALFORMED_QUERY = Columns.RESULT_CODE_MALFORMED_QUERY;
+
+ /** @hide */
+ @IntDef({ FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR,
+ FAIL_REASON_FONT_NOT_FOUND, FAIL_REASON_FONT_UNAVAILABLE,
+ FAIL_REASON_MALFORMED_QUERY })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface FontRequestFailReason {}
+
+ public FontRequestCallback() {}
+
+ /**
+ * Called then a Typeface request done via {@link Typeface#create(FontRequest,
+ * FontRequestCallback)} is complete. Note that this method will not be called if
+ * {@link #onTypefaceRequestFailed(int)} is called instead.
+ * @param typeface The Typeface object retrieved.
+ */
+ public void onTypefaceRetrieved(Typeface typeface) {}
+
+ /**
+ * Called when a Typeface request done via {@link Typeface#create(FontRequest,
+ * FontRequestCallback)} fails.
+ * @param reason One of {@link #FAIL_REASON_PROVIDER_NOT_FOUND},
+ * {@link #FAIL_REASON_FONT_NOT_FOUND},
+ * {@link #FAIL_REASON_FONT_LOAD_ERROR},
+ * {@link #FAIL_REASON_FONT_UNAVAILABLE} or
+ * {@link #FAIL_REASON_MALFORMED_QUERY}.
+ */
+ public void onTypefaceRequestFailed(@FontRequestFailReason int reason) {}
+ }
+
+ /**
+ * Create a typeface object given a font request. The font will be asynchronously fetched,
+ * therefore the result is delivered to the given callback. See {@link FontRequest}.
+ * Only one of the methods in callback will be invoked, depending on whether the request
+ * succeeds or fails. These calls will happen on the caller thread.
+ * @param context A context to be used for fetching from font provider.
+ * @param request A {@link FontRequest} object that identifies the provider and query for the
+ * request. May not be null.
+ * @param callback A callback that will be triggered when results are obtained. May not be null.
+ * @param handler A handler to be processed the font fetching.
+ */
+ public static void requestFont(@NonNull Context context, @NonNull FontRequest request,
+ @NonNull FontRequestCallback callback, @NonNull Handler handler) {
+
+ final Handler callerThreadHandler = new Handler();
+ handler.post(() -> {
+ // TODO: Cache the result.
+ FontFamilyResult result;
+ try {
+ result = fetchFonts(context, null /* cancellation signal */, request);
+ } catch (NameNotFoundException e) {
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND));
+ return;
+ }
+
+ if (result.getStatusCode() != FontFamilyResult.STATUS_OK) {
+ switch (result.getStatusCode()) {
+ case FontFamilyResult.STATUS_WRONG_CERTIFICATES:
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES));
+ return;
+ case FontFamilyResult.STATUS_UNEXPECTED_DATA_PROVIDED:
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR));
+ return;
+ default:
+ // fetchFont returns unexpected status type. Fallback to load error.
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR));
+ return;
+ }
+ }
+
+ final FontInfo[] fonts = result.getFonts();
+ if (fonts == null || fonts.length == 0) {
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND));
+ return;
+ }
+ for (final FontInfo font : fonts) {
+ if (font.getResultCode() != Columns.RESULT_CODE_OK) {
+ // We proceed if all font entry is ready to use. Otherwise report the first
+ // error.
+ final int resultCode = font.getResultCode();
+ if (resultCode < 0) {
+ // Negative values are reserved for internal errors. Fallback to load error.
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR));
+ } else {
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ resultCode));
+ }
+ return;
+ }
+ }
+
+ final Typeface typeface = buildTypeface(context, null /* cancellation signal */, fonts);
+ if (typeface == null) {
+ // Something went wrong during reading font files. This happens if the given font
+ // file is an unsupported font type.
+ callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR));
+ return;
+ }
+
+ callerThreadHandler.post(() -> callback.onTypefaceRetrieved(typeface));
+ });
+ }
+
+ /**
+ * 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);
+ return new Typeface.Builder(fonts, uriBuffer)
+ .setFallback(fallbackFontName)
+ .setWeight(weight)
+ .setItalic(italic)
+ .build();
+ }
+
+ /**
+ * 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()) {
@@ -230,16 +681,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.
@@ -249,8 +695,6 @@
return info;
}
}
- Log.e(TAG, "Certificates don't match for given provider " + providerAuthority);
- receiver.send(RESULT_CODE_WRONG_CERTIFICATES, null);
return null;
}
@@ -266,7 +710,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;
}
@@ -278,7 +723,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());
@@ -288,9 +733,10 @@
/** @hide */
@VisibleForTesting
- public void getFontFromProvider(FontRequest request, ResultReceiver receiver,
- String authority) {
- ArrayList<FontResult> result = null;
+ 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();
@@ -298,15 +744,14 @@
.authority(authority)
.appendPath("file")
.build();
- try (Cursor cursor = mContext.getContentResolver().query(uri, new String[] { Columns._ID,
+ 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);) {
+ "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);
@@ -316,23 +761,13 @@
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);
@@ -341,42 +776,27 @@
long id = cursor.getLong(fileIdColumnIndex);
fileUri = ContentUris.withAppendedId(fileBaseUri, 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 b037ee5..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);
}
/**
@@ -7094,6 +7095,7 @@
INSTANT_APP_SETTINGS.add(ANDROID_ID);
INSTANT_APP_SETTINGS.add(PACKAGE_VERIFIER_USER_CONSENT);
+ INSTANT_APP_SETTINGS.add(ALLOW_MOCK_LOCATION);
}
/**
@@ -10331,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/speech/tts/SynthesisCallback.java b/core/java/android/speech/tts/SynthesisCallback.java
index e535cfa..f5e5f4d 100644
--- a/core/java/android/speech/tts/SynthesisCallback.java
+++ b/core/java/android/speech/tts/SynthesisCallback.java
@@ -151,6 +151,9 @@
* listener ({@link UtteranceProgressListener#onRangeStart}) at the moment that frame has been
* reached by the playback head.
*
+ * <p>This information can be used by the client, for example, to highlight ranges of the text
+ * while it is spoken.
+ *
* <p>The markerInFrames is a frame index into the audio for this synthesis request, i.e. into
* the concatenation of the audio bytes sent to audioAvailable for this synthesis request. The
* definition of a frame depends on the format given by {@link #start}. See {@link AudioFormat}
diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java
index 59ee8f3..ef81f12 100644
--- a/core/java/android/speech/tts/UtteranceProgressListener.java
+++ b/core/java/android/speech/tts/UtteranceProgressListener.java
@@ -128,6 +128,9 @@
* <p>This method is called when the audio is expected to start playing on the speaker. Note
* that this is different from {@link #onAudioAvailable} which is called as soon as the audio is
* generated.
+
+ * <p>This information can be used, for example, to highlight ranges of the text while it is
+ * spoken.
*
* <p>Only called if the engine supplies timing information by calling {@link
* SynthesisCallback#rangeStart(int, int, int)}.
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/util/LauncherIcons.java b/core/java/android/util/LauncherIcons.java
index e5aa2b5..89b9646 100644
--- a/core/java/android/util/LauncherIcons.java
+++ b/core/java/android/util/LauncherIcons.java
@@ -20,11 +20,8 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
-import android.graphics.Path;
-import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -49,7 +46,7 @@
public LauncherIcons(Context context) {
mRes = context.getResources();
DisplayMetrics metrics = mRes.getDisplayMetrics();
- mShadowInset = (int) metrics.density / DisplayMetrics.DENSITY_DEFAULT;
+ mShadowInset = (int)(2 * metrics.density);
mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
Paint.FILTER_BITMAP_FLAG));
mIconSize = (int) mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
@@ -91,7 +88,6 @@
return mShadowBitmap;
}
- int shadowSize = mIconSize - mShadowInset;
mShadowBitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ALPHA_8);
mCanvas.setBitmap(mShadowBitmap);
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/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/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..f9f10af 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -16,7 +16,6 @@
package android.widget;
-import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY;
@@ -59,6 +58,7 @@
import android.graphics.fonts.FontVariationAxis;
import android.icu.text.DecimalFormatSymbols;
import android.os.AsyncTask;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
@@ -408,7 +408,7 @@
public Drawables(Context context) {
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
- mIsRtlCompatibilityMode = targetSdkVersion < JELLY_BEAN_MR1
+ mIsRtlCompatibilityMode = targetSdkVersion < VERSION_CODES.JELLY_BEAN_MR1
|| !context.getApplicationInfo().hasRtlSupport();
mOverride = false;
}
@@ -1363,7 +1363,7 @@
== (EditorInfo.TYPE_CLASS_NUMBER | EditorInfo.TYPE_NUMBER_VARIATION_PASSWORD);
mUseInternationalizedInput =
- context.getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O;
+ context.getApplicationInfo().targetSdkVersion >= VERSION_CODES.O;
if (inputMethod != null) {
Class<?> c;
@@ -1408,7 +1408,7 @@
} else if (numeric != 0) {
createEditorIfNeeded();
mEditor.mKeyListener = DigitsKeyListener.getInstance(
- mUseInternationalizedInput ? getTextLocale() : null,
+ null, // locale
(numeric & SIGNED) != 0,
(numeric & DECIMAL) != 0);
inputType = mEditor.mKeyListener.getInputType();
@@ -3400,11 +3400,14 @@
return mTextPaint.getTextLocales();
}
- private void changeListenerLocaleTo(@NonNull Locale locale) {
+ private void changeListenerLocaleTo(@Nullable Locale locale) {
if (mListenerChanged) {
// If a listener has been explicitly set, don't change it. We may break something.
return;
}
+ // The following null check is not absolutely necessary since all calling points of
+ // changeListenerLocaleTo() guarantee a non-null mEditor at the moment. But this is left
+ // here in case others would want to call this method in the future.
if (mEditor != null) {
KeyListener listener = mEditor.mKeyListener;
if (listener instanceof DigitsKeyListener) {
@@ -3418,8 +3421,17 @@
} else {
return;
}
+ final boolean wasPasswordType = isPasswordInputType(mEditor.mInputType);
setKeyListenerOnly(listener);
setInputTypeFromEditor();
+ if (wasPasswordType) {
+ final int newInputClass = mEditor.mInputType & EditorInfo.TYPE_MASK_CLASS;
+ if (newInputClass == EditorInfo.TYPE_CLASS_TEXT) {
+ mEditor.mInputType |= EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
+ } else if (newInputClass == EditorInfo.TYPE_CLASS_NUMBER) {
+ mEditor.mInputType |= EditorInfo.TYPE_NUMBER_VARIATION_PASSWORD;
+ }
+ }
}
}
@@ -3434,7 +3446,6 @@
public void setTextLocale(@NonNull Locale locale) {
mLocalesChanged = true;
mTextPaint.setTextLocale(locale);
- changeListenerLocaleTo(locale);
if (mLayout != null) {
nullLayouts();
requestLayout();
@@ -3456,7 +3467,6 @@
public void setTextLocales(@NonNull @Size(min = 1) LocaleList locales) {
mLocalesChanged = true;
mTextPaint.setTextLocales(locales);
- changeListenerLocaleTo(locales.get(0));
if (mLayout != null) {
nullLayouts();
requestLayout();
@@ -3468,9 +3478,7 @@
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (!mLocalesChanged) {
- final LocaleList locales = LocaleList.getDefault();
- mTextPaint.setTextLocales(locales);
- changeListenerLocaleTo(locales.get(0));
+ mTextPaint.setTextLocales(LocaleList.getDefault());
if (mLayout != null) {
nullLayouts();
requestLayout();
@@ -5586,6 +5594,29 @@
mEditor.mInputType = type;
}
+ /**
+ * @return {@code null} if the key listener should use pre-O (locale-independent). Otherwise
+ * a {@code Locale} object that can be used to customize key various listeners.
+ * @see DateKeyListener#getInstance(Locale)
+ * @see DateTimeKeyListener#getInstance(Locale)
+ * @see DigitsKeyListener#getInstance(Locale)
+ * @see TimeKeyListener#getInstance(Locale)
+ */
+ @Nullable
+ private Locale getCustomLocaleForKeyListenerOrNull() {
+ if (!mUseInternationalizedInput) {
+ // If the application does not target O, stick to the previous behavior.
+ return null;
+ }
+ final LocaleList locales = getImeHintLocales();
+ if (locales == null) {
+ // If the application does not explicitly specify IME hint locale, also stick to the
+ // previous behavior.
+ return null;
+ }
+ return locales.get(0);
+ }
+
private void setInputType(int type, boolean direct) {
final int cls = type & EditorInfo.TYPE_MASK_CLASS;
KeyListener input;
@@ -5603,15 +5634,26 @@
}
input = TextKeyListener.getInstance(autotext, cap);
} else if (cls == EditorInfo.TYPE_CLASS_NUMBER) {
+ final Locale locale = getCustomLocaleForKeyListenerOrNull();
input = DigitsKeyListener.getInstance(
- mUseInternationalizedInput ? getTextLocale() : null,
+ locale,
(type & EditorInfo.TYPE_NUMBER_FLAG_SIGNED) != 0,
(type & EditorInfo.TYPE_NUMBER_FLAG_DECIMAL) != 0);
- if (mUseInternationalizedInput) {
- type = input.getInputType(); // Override type, if necessary for i18n.
+ if (locale != null) {
+ // Override type, if necessary for i18n.
+ int newType = input.getInputType();
+ final int newClass = newType & EditorInfo.TYPE_MASK_CLASS;
+ if (newClass != EditorInfo.TYPE_CLASS_NUMBER) {
+ // The class is different from the original class. So we need to override
+ // 'type'. But we want to keep the password flag if it's there.
+ if ((type & EditorInfo.TYPE_NUMBER_VARIATION_PASSWORD) != 0) {
+ newType |= EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
+ }
+ type = newType;
+ }
}
} else if (cls == EditorInfo.TYPE_CLASS_DATETIME) {
- final Locale locale = mUseInternationalizedInput ? getTextLocale() : null;
+ final Locale locale = getCustomLocaleForKeyListenerOrNull();
switch (type & EditorInfo.TYPE_MASK_VARIATION) {
case EditorInfo.TYPE_DATETIME_VARIATION_DATE:
input = DateKeyListener.getInstance(locale);
@@ -5884,6 +5926,9 @@
* Change "hint" locales associated with the text view, which will be reported to an IME with
* {@link EditorInfo#hintLocales} when it has focus.
*
+ * Starting with Android O, this also causes internationalized listeners to be created (or
+ * change locale) based on the first locale in the input locale list.
+ *
* <p><strong>Note:</strong> If you want new "hint" to take effect immediately you need to
* call {@link InputMethodManager#restartInput(View)}.</p>
* @param hintLocales List of the languages that the user is supposed to switch to no matter
@@ -5895,6 +5940,9 @@
createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.imeHintLocales = hintLocales;
+ if (mUseInternationalizedInput) {
+ changeListenerLocaleTo(hintLocales == null ? null : hintLocales.get(0));
+ }
}
/**
@@ -8470,7 +8518,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/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 3010dc1..fc90fb3 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -45,21 +45,24 @@
constexpr jint RESOLVE_BY_FONT_TABLE = -1;
struct NativeFamilyBuilder {
+ NativeFamilyBuilder(uint32_t langId, int variant)
+ : langId(langId), variant(variant), allowUnsupportedFont(false) {}
uint32_t langId;
int variant;
+ bool allowUnsupportedFont;
std::vector<minikin::Font> fonts;
std::vector<minikin::FontVariation> axes;
};
static jlong FontFamily_initBuilder(JNIEnv* env, jobject clazz, jstring lang, jint variant) {
- NativeFamilyBuilder* builder = new NativeFamilyBuilder();
+ NativeFamilyBuilder* builder;
if (lang != nullptr) {
ScopedUtfChars str(env, lang);
- builder->langId = minikin::FontStyle::registerLanguageList(str.c_str());
+ builder = new NativeFamilyBuilder(
+ minikin::FontStyle::registerLanguageList(str.c_str()), variant);
} else {
- builder->langId = minikin::FontStyle::registerLanguageList("");
+ builder = new NativeFamilyBuilder(minikin::FontStyle::registerLanguageList(""), variant);
}
- builder->variant = variant;
return reinterpret_cast<jlong>(builder);
}
@@ -67,12 +70,22 @@
if (builderPtr == 0) {
return 0;
}
+ std::unique_ptr<NativeFamilyBuilder> builder(
+ reinterpret_cast<NativeFamilyBuilder*>(builderPtr));
+ std::shared_ptr<minikin::FontFamily> family = std::make_shared<minikin::FontFamily>(
+ builder->langId, builder->variant, std::move(builder->fonts));
+ if (family->getCoverage().length() == 0 && !builder->allowUnsupportedFont) {
+ return 0;
+ }
+ return reinterpret_cast<jlong>(new FontFamilyWrapper(std::move(family)));
+}
+
+static void FontFamily_allowUnsupportedFont(jlong builderPtr) {
+ if (builderPtr == 0) {
+ return;
+ }
NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
- FontFamilyWrapper* family = new FontFamilyWrapper(
- std::make_shared<minikin::FontFamily>(
- builder->langId, builder->variant, std::move(builder->fonts)));
- delete builder;
- return reinterpret_cast<jlong>(family);
+ builder->allowUnsupportedFont = true;
}
static void FontFamily_abort(jlong builderPtr) {
@@ -258,6 +271,7 @@
static const JNINativeMethod gFontFamilyMethods[] = {
{ "nInitBuilder", "(Ljava/lang/String;I)J", (void*)FontFamily_initBuilder },
{ "nCreateFamily", "(J)J", (void*)FontFamily_create },
+ { "nAllowUnsupportedFont", "(J)V", (void*)FontFamily_allowUnsupportedFont },
{ "nAbort", "(J)V", (void*)FontFamily_abort },
{ "nUnrefFamily", "(J)V", (void*)FontFamily_unref },
{ "nAddFont", "(JLjava/nio/ByteBuffer;III)Z", (void*)FontFamily_addFont },
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index d0b07d0..95d43c6 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -42,6 +42,13 @@
return reinterpret_cast<jlong>(face);
}
+static jlong Typeface_createFromTypefaceWithExactStyle(JNIEnv* env, jobject, jlong nativeInstance,
+ jint weight, jboolean italic) {
+ Typeface* baseTypeface = reinterpret_cast<Typeface*>(nativeInstance);
+ return reinterpret_cast<jlong>(
+ Typeface::createFromTypefaceWithStyle(baseTypeface, weight, italic));
+}
+
static jlong Typeface_createFromTypefaceWithVariation(JNIEnv* env, jobject, jlong familyHandle,
jobject listOfAxis) {
std::vector<minikin::FontVariation> variations;
@@ -75,6 +82,11 @@
return face->fSkiaStyle;
}
+static jint Typeface_getBaseWeight(JNIEnv* env, jobject obj, jlong faceHandle) {
+ Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
+ return face->fBaseWeight;
+}
+
static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) {
ScopedLongArrayRO families(env, familyArray);
std::vector<std::shared_ptr<minikin::FontFamily>> familyVec;
@@ -113,11 +125,14 @@
static const JNINativeMethod gTypefaceMethods[] = {
{ "nativeCreateFromTypeface", "(JI)J", (void*)Typeface_createFromTypeface },
+ { "nativeCreateFromTypefaceWithExactStyle", "(JIZ)J",
+ (void*)Typeface_createFromTypefaceWithExactStyle },
{ "nativeCreateFromTypefaceWithVariation", "(JLjava/util/List;)J",
(void*)Typeface_createFromTypefaceWithVariation },
{ "nativeCreateWeightAlias", "(JI)J", (void*)Typeface_createWeightAlias },
{ "nativeUnref", "(J)V", (void*)Typeface_unref },
{ "nativeGetStyle", "(J)I", (void*)Typeface_getStyle },
+ { "nativeGetBaseWeight", "(J)I", (void*)Typeface_getBaseWeight },
{ "nativeCreateFromArray", "([J)J",
(void*)Typeface_createFromArray },
{ "nativeSetDefault", "(J)V", (void*)Typeface_setDefault },
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_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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8895877..57dfeb5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -37,6 +37,7 @@
<protected-broadcast android:name="android.intent.action.BOOT_COMPLETED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_INSTALL" />
<protected-broadcast android:name="android.intent.action.PACKAGE_ADDED" />
+ <protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_ADDED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_REPLACED" />
<protected-broadcast android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_REMOVED" />
diff --git a/core/res/res/drawable/scrollbar_handle_material.xml b/core/res/res/drawable/scrollbar_handle_material.xml
index f020112..33efbba 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/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 3359b5d..2155c8f 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Stoor <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> in <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Stoor <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> in <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8e247aeb..41a0153 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 9c42197..570e3c4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1859,10 +1859,8 @@
<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_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>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index c2a0690..6da988a 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1735,10 +1735,8 @@
<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_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> etiketində yadda saxlanılsın?"</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> etiketində yadda saxlanılsın?"</string>
<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>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index ed3fb22..cfb8177 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index f0b4a08..0a63cdf 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Vols desar la informació dels camps <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Vols desar la informació dels camps <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> a <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 306a393..0b9b95d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1797,10 +1797,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Má se <xliff:g id="TYPE_0">%1$s</xliff:g> a <xliff:g id="TYPE_1">%2$s</xliff:g> uložit do služby <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Má se <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="TYPE_2">%3$s</xliff:g> uložit do služby <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 962a089..1708834 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Vil du gemme <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> til <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Vil du gemme <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> til <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f743f7d..6e930ff 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"\"<xliff:g id="TYPE_0">%1$s</xliff:g>\" und \"<xliff:g id="TYPE_1">%2$s</xliff:g>\" in \"<xliff:g id="LABEL">%3$s</xliff:g>\" speichern?"</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>\" und \"<xliff:g id="TYPE_2">%3$s</xliff:g>\" in \"<xliff:g id="LABEL">%4$s</xliff:g>\" speichern?"</string>
<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>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ec49827..99fa2e5 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index e764a19..df55b6c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"¿Guardar <xliff:g id="TYPE_0">%1$s</xliff:g> y <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">"¿Guardar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <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">"Guardar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No, gracias"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"contraseña"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 67c5372..c46146d 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"¿Guardar <xliff:g id="TYPE_0">%1$s</xliff:g> y <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">"¿Guardar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <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">"Guardar"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"No, gracias"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"contraseña"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index e18f177..4bd9ef8 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Kas salvestada <xliff:g id="TYPE_0">%1$s</xliff:g> ja <xliff:g id="TYPE_1">%2$s</xliff:g> teenusesse <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Kas salvestada <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ja <xliff:g id="TYPE_2">%3$s</xliff:g> teenusesse <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 6e0d929..5c1b423ca 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1736,10 +1736,8 @@
<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_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g> eta <xliff:g id="TYPE_1">%2$s</xliff:g> gorde nahi dituzu <xliff:g id="LABEL">%3$s</xliff:g> behar denean erabiltzeko?"</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> eta <xliff:g id="TYPE_2">%3$s</xliff:g> gorde nahi dituzu <xliff:g id="LABEL">%4$s</xliff:g> behar denean erabiltzeko?"</string>
<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>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 0cec9f9..7312fa6 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 9384ae5..5d12753 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Tallennetaanko <xliff:g id="TYPE_0">%1$s</xliff:g> ja <xliff:g id="TYPE_1">%2$s</xliff:g> palveluun <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Tallennetaanko <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ja <xliff:g id="TYPE_2">%3$s</xliff:g> palveluun <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index de4c728..6bcc8ae 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Enregistrer <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> sous <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Enregistrer <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> sous <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 3db6d83..fdea62a 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Enregistrer <xliff:g id="TYPE_0">%1$s</xliff:g> et <xliff:g id="TYPE_1">%2$s</xliff:g> sur <xliff:g id="LABEL">%3$s</xliff:g> ?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Enregistrer <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> et <xliff:g id="TYPE_2">%3$s</xliff:g> sur <xliff:g id="LABEL">%4$s</xliff:g> ?"</string>
<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>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 6b771fd..82481d5 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1733,8 +1733,7 @@
<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) -->
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 822f740..9e5c53e 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Menti a(z) <xliff:g id="LABEL">%3$s</xliff:g> szolgáltatásba a következőket: <xliff:g id="TYPE_0">%1$s</xliff:g> és <xliff:g id="TYPE_1">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Menti a(z) <xliff:g id="LABEL">%4$s</xliff:g> szolgáltatásba a következőket: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> és <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 7a91c68..d6a75d5 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index b65805e..06850c8 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Salvare <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> su <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Salvare <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> su <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index fe61600..846ce56 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1797,10 +1797,8 @@
<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_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>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 071bc0b..f627b22 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 0fce14b..6157f6b 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"გსურთ, <xliff:g id="LABEL">%3$s</xliff:g>-ში შეინახოთ <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"გსურთ, <xliff:g id="LABEL">%4$s</xliff:g>-ში შეინახოთ <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"შენახვა"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"არა, გმადლობთ"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"პაროლი"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 236e201..7e97f95 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1737,10 +1737,8 @@
<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_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>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 45bff7a..94f4df8 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1736,10 +1736,8 @@
<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_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>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 8133d13..a24eb06 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"<xliff:g id="LABEL">%3$s</xliff:g>에 <xliff:g id="TYPE_0">%1$s</xliff:g> 및 <xliff:g id="TYPE_1">%2$s</xliff:g>을(를) 저장하시겠습니까?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="LABEL">%4$s</xliff:g>에 <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> 및 <xliff:g id="TYPE_2">%3$s</xliff:g>을(를) 저장하시겠습니까?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"저장"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"사용 안함"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"비밀번호"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 2040bdf..e57c851 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index c84ab90..e98c66c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1797,10 +1797,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Išsaugoti <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> sistemoje „<xliff:g id="LABEL">%3$s</xliff:g>“?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Išsaugoti <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> sistemoje „<xliff:g id="LABEL">%4$s</xliff:g>“?"</string>
<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>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f16b129..4251a52 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1766,10 +1766,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Vai saglabāt informāciju (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>) iezīmē <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Vai saglabāt informāciju (<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>) iezīmē <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 5cfc234b..8f80f1ad 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1736,10 +1736,8 @@
<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_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>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index fb842b2..88aacda 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1733,10 +1733,8 @@
<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_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>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 538d626..4769676 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1733,8 +1733,7 @@
<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) -->
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index ef5883a..e414985 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1735,10 +1735,8 @@
<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_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">"Tidak, terima kasih"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"kata laluan"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index ad0602e..5252422 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/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>
@@ -1736,10 +1736,8 @@
<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_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>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 974d55f..9c638ec 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Vil du lagre <xliff:g id="TYPE_0">%1$s</xliff:g> og <xliff:g id="TYPE_1">%2$s</xliff:g> til <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Vil du lagre <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> og <xliff:g id="TYPE_2">%3$s</xliff:g> til <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 8161fb1..86c18d6 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1741,10 +1741,8 @@
<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_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>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 15c8ff3..af8c0a2 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g> en <xliff:g id="TYPE_1">%2$s</xliff:g> opslaan in <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> en <xliff:g id="TYPE_2">%3$s</xliff:g> opslaan in <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index ea1194a..71fd285 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1733,14 +1733,11 @@
<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_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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d7572a0..dee76d5 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1797,10 +1797,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Zapisać: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> w: <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Zapisać: <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> w: <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1231a8b..2212c06 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Salvar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> em <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Salvar <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> em <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c533a03..241b2fe 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Pretende guardar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> no <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Pretende guardar <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> no <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1231a8b..2212c06 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Salvar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> em <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Salvar <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> em <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 8a6b349..f347a8e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1766,10 +1766,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Salvați <xliff:g id="TYPE_0">%1$s</xliff:g> și <xliff:g id="TYPE_1">%2$s</xliff:g> în <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Salvați <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> în <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 40fe776..3ac621a 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1797,10 +1797,8 @@
<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_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>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index cd4cebd..6c595fb 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1737,10 +1737,8 @@
<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_title_with_2types" msgid="8875796560521962098">"<xliff:g id="LABEL">%3$s</xliff:g> වෙත <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> සුරකින්නද?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="LABEL">%4$s</xliff:g> වෙත <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> සුරකින්නද?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"සුරකින්න"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"එපා ස්තූතියි"</string>
<string name="autofill_save_type_password" msgid="5288448918465971568">"මුරපදය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 71411f7..af5268e 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1797,10 +1797,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Uložiť <xliff:g id="TYPE_0">%1$s</xliff:g> a <xliff:g id="TYPE_1">%2$s</xliff:g> do služby <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Uložiť <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="TYPE_2">%3$s</xliff:g> do služby <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5b76e79..877add7 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1797,10 +1797,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Želite shraniti <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> v <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Želite shraniti <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> v <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index d26b652..b645553 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1736,10 +1736,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Të ruhen <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> te <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Të ruhen <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> te <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 15456f8..6e13582 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1766,10 +1766,8 @@
<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_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>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index e7b12f0..664a038 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1733,10 +1733,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Ungependa kuhifadhi <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> kwenye <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Ungependa kuhifadhi <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> kwenye <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6c489fd..0fb49d5 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1736,10 +1736,8 @@
<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_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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 994906b..ed22eef 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 3e14b14..8b5962f 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"I-save ang <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> sa <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"I-save ang <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 <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index da4ed4f..7be1384 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g> ve <xliff:g id="TYPE_1">%2$s</xliff:g> bilgileri <xliff:g id="LABEL">%3$s</xliff:g> hizmetine kaydedilsin mi?"</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> ve <xliff:g id="TYPE_2">%3$s</xliff:g> bilgileri <xliff:g id="LABEL">%4$s</xliff:g> hizmetine kaydedilsin mi?"</string>
<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>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index dcde3f6b..ccaa412 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1736,10 +1736,8 @@
<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_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>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 7592078..ee2438f 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -796,7 +796,7 @@
<string name="factorytest_failed" msgid="5410270329114212041">"Ishlab chiqarish sinovi amalga oshmadi"</string>
<string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST amali faqatgina /system/app ichiga o‘rnatilgan paketlar bilan ishlay oladi."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST amalini bajarish uchun birorta ham paket topilmadi."</string>
- <string name="factorytest_reboot" msgid="6320168203050791643">"O‘chirib-yoqish"</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"O‘chirib yoqish"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\"dagi sahifa buni xabar qilmoqda:"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Tasdiqlash"</string>
@@ -1146,7 +1146,7 @@
<string name="sim_done_button" msgid="827949989369963775">"Tayyor"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM karta qo‘shildi"</string>
<string name="sim_added_message" msgid="6599945301141050216">"Uyali tarmoqqa ulanish uchun qurilmangizni o‘chirib-yoqing."</string>
- <string name="sim_restart_button" msgid="4722407842815232347">"O‘chirib-yoqish"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"O‘chirib yoqish"</string>
<string name="carrier_app_dialog_message" msgid="7066156088266319533">"Yangi SIM karta to‘g‘ri ishlashi uchun operator ilovasini o‘rnatib, ochish kerak bo‘ladi."</string>
<string name="carrier_app_dialog_button" msgid="7900235513678617329">"ILOVANI YUKLAB OLING"</string>
<string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"HOZIR EMAS"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 6b61b56..c85f413 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1735,10 +1735,8 @@
<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_title_with_2types" msgid="8875796560521962098">"Lưu <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> vào <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Lưu <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> vào <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
<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>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 0202a99..1daecdd 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index da5c464..902cfea 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c7146a7..91c5df3 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1735,10 +1735,8 @@
<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_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>
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/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 3e4b66d7..5696468 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -322,6 +322,10 @@
your application running at all times. -->
<attr name="persistent" format="boolean" />
+ <!-- If set, the "persistent" attribute will only be honored if the feature
+ specified here is present on the device. -->
+ <attr name="persistentFeature" format="string" />
+
<!-- Flag to specify if this application needs to be present for all users. Only pre-installed
applications can request this feature. Default value is false. -->
<attr name="requiredForAllUsers" format="boolean" />
@@ -1358,6 +1362,7 @@
for normal behavior. -->
<attr name="hasCode" format="boolean" />
<attr name="persistent" />
+ <attr name="persistentFeature" />
<attr name="requiredForAllUsers" />
<!-- Specify whether the components in this application are enabled or not (that is, can be
instantiated by the system).
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 860c631..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>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f364e70..31ece50 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,8 @@
<public name="iconTintMode" />
<public name="maxAspectRatio"/>
<public name="iconSpaceReserved"/>
+ <public name="defaultFocusHighlightEnabled" />
+ <public name="persistentFeature"/>
</public-group>
<public-group type="style" first-id="0x010302e0">
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 8bbb929..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">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 78f971f..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" />
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/database/PageViewCursorTest.java b/core/tests/coretests/src/android/database/PageViewCursorTest.java
deleted file mode 100644
index fba6aaf..0000000
--- a/core/tests/coretests/src/android/database/PageViewCursorTest.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.database;
-
-import static com.android.internal.util.ArrayUtils.contains;
-import static com.android.internal.util.Preconditions.checkArgument;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
-import android.util.MathUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.Random;
-
-@RunWith(AndroidJUnit4.class)
-public class PageViewCursorTest {
-
- private static final int ITEM_COUNT = 20;
-
- private static final String NAME_COLUMN = "name";
- private static final String NUM_COLUMN = "num";
-
- private static final String[] COLUMNS = new String[] {
- NAME_COLUMN,
- NUM_COLUMN
- };
-
- private static final String[] NAMES = new String[] {
- "000",
- "111",
- "222",
- "333",
- "444",
- "555",
- "666",
- "777",
- "888",
- "999",
- "aaa",
- "bbb",
- "ccc",
- "ddd",
- "eee",
- "fff",
- "ggg",
- "hhh",
- "iii",
- "jjj"
- };
-
- private MatrixCursor mDelegate;
- private PageViewCursor mCursor;
-
- @Before
- public void setUp() {
- Random rand = new Random();
-
- mDelegate = new MatrixCursor(COLUMNS);
- for (int i = 0; i < ITEM_COUNT; i++) {
- MatrixCursor.RowBuilder row = mDelegate.newRow();
- row.add(NAME_COLUMN, NAMES[i]);
- row.add(NUM_COLUMN, rand.nextInt());
- }
-
- mCursor = new PageViewCursor(mDelegate, createArgs(10, 5));
- }
-
- @Test
- public void testPage_Size() {
- assertEquals(5, mCursor.getCount());
- }
-
- @Test
- public void testPage_TotalSize() {
- assertEquals(ITEM_COUNT, mCursor.getExtras().getInt(ContentResolver.EXTRA_TOTAL_SIZE));
- }
-
- @Test
- public void testPage_OffsetExceedsCursorCount_EffectivelyEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(ITEM_COUNT * 2, 5));
- assertEquals(0, mCursor.getCount());
- }
-
- @Test
- public void testMoveToPosition() {
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(4));
- assertEquals(NAMES[14], mCursor.getString(0));
-
- // and then back down again for good measure.
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToPosition_MoveToSamePosition_NoOp() {
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- assertTrue(mCursor.moveToPosition(1));
- assertEquals(NAMES[11], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToPosition_PositionOutOfBounds_MovesToBeforeFirst() {
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
-
- // move before
- assertFalse(mCursor.moveToPosition(-12));
- assertTrue(mCursor.isBeforeFirst());
- }
-
- @Test
- public void testMoveToPosition_PositionOutOfBounds_MovesToAfterLast() {
- assertTrue(mCursor.moveToPosition(0));
- assertEquals(NAMES[10], mCursor.getString(0));
-
- assertFalse(mCursor.moveToPosition(222));
- assertTrue(mCursor.isAfterLast());
- }
-
- @Test
- public void testPosition() {
- assertEquals(-1, mCursor.getPosition());
- }
-
- @Test
- public void testIsBeforeFirst() {
- assertTrue(mCursor.isBeforeFirst());
- mCursor.moveToFirst();
- assertFalse(mCursor.isBeforeFirst());
- }
-
- @Test
- public void testCount_ZeroForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
- assertEquals(0, mCursor.getCount());
- }
-
- @Test
- public void testIsBeforeFirst_TrueForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
- assertTrue(mCursor.isBeforeFirst());
- }
-
- @Test
- public void testIsAfterLast() {
- assertFalse(mCursor.isAfterLast());
- mCursor.moveToLast();
- mCursor.moveToNext();
- assertTrue(mCursor.isAfterLast());
- }
-
- @Test
- public void testIsAfterLast_TrueForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
- assertTrue(mCursor.isAfterLast());
- }
-
- @Test
- public void testIsFirst() {
- assertFalse(mCursor.isFirst());
- mCursor.moveToFirst();
- assertTrue(mCursor.isFirst());
- }
-
- @Test
- public void testIsLast() {
- assertFalse(mCursor.isLast());
- mCursor.moveToLast();
- assertTrue(mCursor.isLast());
- }
-
- @Test
- public void testMove() {
- // note that initial position is -1, so moving
- // 2 will only put as at 1.
- mCursor.move(2);
- assertEquals(NAMES[11], mCursor.getString(0));
- mCursor.move(-1);
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToFist() {
- mCursor.moveToPosition(3);
- mCursor.moveToFirst();
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToLast() {
- mCursor.moveToLast();
- assertEquals(NAMES[14], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToNext() {
- // default position is -1, so next is 0.
- mCursor.moveToNext();
- assertEquals(NAMES[10], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToNext_AfterLastReturnsFalse() {
- mCursor.moveToLast();
- assertFalse(mCursor.moveToNext());
- }
-
- @Test
- public void testMoveToPrevious() {
- mCursor.moveToPosition(3);
- mCursor.moveToPrevious();
- assertEquals(NAMES[12], mCursor.getString(0));
- }
-
- @Test
- public void testMoveToPrevious_BeforeFirstReturnsFalse() {
- assertFalse(mCursor.moveToPrevious());
- }
-
- @Test
- public void testWindow_ReadPastEnd() {
- assertFalse(mCursor.moveToPosition(10));
- }
-
- @Test
- public void testLimitOutOfBounds() {
- mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
- assertEquals(15, mCursor.getCount());
- }
-
- @Test
- public void testOffsetOutOfBounds_EmptyResult() {
- mCursor = new PageViewCursor(mDelegate, createArgs(100000, 100));
- assertEquals(0, mCursor.getCount());
- }
-
- @Test
- public void testAddsExtras() {
- mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
- assertTrue(mCursor.getExtras().getBoolean(PageViewCursor.EXTRA_AUTO_PAGED));
- String[] honoredArgs = mCursor.getExtras()
- .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
- }
-
- @Test
- public void testAddsExtras_OnlyOffset() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
- mCursor = new PageViewCursor(mDelegate, args);
- String[] honoredArgs = mCursor.getExtras()
- .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
- assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
- }
-
- @Test
- public void testAddsExtras_OnlyLimit() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
- mCursor = new PageViewCursor(mDelegate, args);
- String[] honoredArgs = mCursor.getExtras()
- .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
- assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
- }
-
- @Test
- public void testGetWindow() {
- mCursor = new PageViewCursor(mDelegate, createArgs(5, 5));
- CursorWindow window = mCursor.getWindow();
- assertEquals(5, window.getNumRows());
- }
-
- @Test
- public void testWraps() {
- Bundle args = createArgs(5, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(5, wrapped.getCount());
- }
-
- @Test
- public void testWraps_NullExtras() {
- Bundle args = createArgs(5, 5);
- mDelegate.setExtras(null);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(5, wrapped.getCount());
- }
-
- @Test
- public void testWraps_WithJustOffset() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(15, wrapped.getCount());
- }
-
- @Test
- public void testWraps_WithJustLimit() {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(wrapped instanceof PageViewCursor);
- assertEquals(5, wrapped.getCount());
- }
-
- @Test
- public void testNoWrap_WithoutPagingArgs() {
- Cursor wrapped = PageViewCursor.wrap(mDelegate, Bundle.EMPTY);
- assertTrue(mDelegate == wrapped);
- }
-
- @Test
- public void testNoWrap_CursorsHasExistingPaging_ByTotalSize() {
- Bundle extras = new Bundle();
- extras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, 5);
- mDelegate.setExtras(extras);
-
- Bundle args = createArgs(5, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(mDelegate == wrapped);
- }
-
- @Test
- public void testNoWrap_CursorsHasExistingPaging_ByHonoredArgs() {
- Bundle extras = new Bundle();
- extras.putStringArray(
- ContentResolver.EXTRA_HONORED_ARGS,
- new String[] {
- ContentResolver.QUERY_ARG_OFFSET,
- ContentResolver.QUERY_ARG_LIMIT
- });
- mDelegate.setExtras(extras);
-
- Bundle args = createArgs(5, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
- assertTrue(mDelegate == wrapped);
- }
-
- private static Bundle createArgs(int offset, int limit) {
- Bundle args = new Bundle();
- args.putInt(ContentResolver.QUERY_ARG_OFFSET, offset);
- args.putInt(ContentResolver.QUERY_ARG_LIMIT, limit);
- return args;
- }
-
- private void assertStringAt(int row, int column, String expected) {
- mCursor.moveToPosition(row);
- assertEquals(expected, mCursor.getString(column));
- }
-}
diff --git a/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java b/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
index 5ade66e..7550cb5 100644
--- a/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
@@ -2,18 +2,22 @@
import static org.junit.Assert.assertTrue;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Region;
import android.test.AndroidTestCase;
import android.util.Log;
+import android.util.PathParser;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
@@ -35,7 +39,7 @@
* Nothing is drawn.
*/
@Test
- public void testDrawWithoutSetBounds() throws Exception {
+ public void testDraw_withoutBounds() throws Exception {
mBackgroundDrawable = new ColorDrawable(Color.BLUE);
mForegroundDrawable = new ColorDrawable(Color.RED);
mIconDrawable = new AdaptiveIconDrawable(mBackgroundDrawable, mForegroundDrawable);
@@ -59,7 +63,7 @@
* When setBound is called, translate accordingly.
*/
@Test
- public void testDrawSetBounds() throws Exception {
+ public void testDraw_withBounds() throws Exception {
int dpi = 4 ;
int top = 18 * dpi;
int left = 18 * dpi;
@@ -102,6 +106,71 @@
}
}
+ /**
+ * When setBound isn't called before getIconMask method is called.
+ * default device config mask is returned.
+ */
+ @Test
+ public void testGetIconMask_withoutBounds() throws Exception {
+ mIconDrawable = new AdaptiveIconDrawable(mBackgroundDrawable, mForegroundDrawable);
+ Path pathFromDrawable = mIconDrawable.getIconMask();
+ Path pathFromDeviceConfig = PathParser.createPathFromPathData(
+ Resources.getSystem().getString(com.android.internal.R.string.config_icon_mask));
+
+ RectF boundFromDrawable = new RectF();
+ pathFromDrawable.computeBounds(boundFromDrawable, true);
+
+ RectF boundFromDeviceConfig = new RectF();
+ pathFromDeviceConfig.computeBounds(boundFromDeviceConfig, true);
+
+ double delta = 0.01;
+ assertEquals("left", boundFromDrawable.left, boundFromDeviceConfig.left, delta);
+ assertEquals("top", boundFromDrawable.top, boundFromDeviceConfig.top, delta);
+ assertEquals("right", boundFromDrawable.right, boundFromDeviceConfig.right, delta);
+ assertEquals("bottom", boundFromDrawable.bottom, boundFromDeviceConfig.bottom, delta);
+
+ assertTrue("path from device config is convex.", pathFromDeviceConfig.isConvex());
+ assertTrue("path from drawable is convex.", pathFromDrawable.isConvex());
+ }
+
+ @Test
+ public void testGetIconMaskAfterSetBounds() throws Exception {
+ int dpi = 4;
+ int top = 18 * dpi;
+ int left = 18 * dpi;
+ int right = 90 * dpi;
+ int bottom = 90 * dpi;
+
+ mIconDrawable = new AdaptiveIconDrawable(mBackgroundDrawable, mForegroundDrawable);
+ mIconDrawable.setBounds(left, top, right, bottom);
+ RectF maskBounds = new RectF();
+
+ mIconDrawable.getIconMask().computeBounds(maskBounds, true);
+
+ double delta = 0.01;
+ assertEquals("left", left, maskBounds.left, delta);
+ assertEquals("top", top, maskBounds.top, delta);
+ assertEquals("right", right, maskBounds.right, delta);
+ assertEquals("bottom", bottom, maskBounds.bottom, delta);
+
+ assertTrue(mIconDrawable.getIconMask().isConvex());
+ }
+
+ @Test
+ public void testGetOutline_withBounds() throws Exception {
+ int dpi = 4;
+ int top = 18 * dpi;
+ int left = 18 * dpi;
+ int right = 90 * dpi;
+ int bottom = 90 * dpi;
+
+ mIconDrawable = new AdaptiveIconDrawable(mBackgroundDrawable, mForegroundDrawable);
+ mIconDrawable.setBounds(left, top, right, bottom);
+ Outline outline = new Outline();
+ mIconDrawable.getOutline(outline);
+ assertTrue("outline path should be convex", outline.mPath.isConvex());
+ }
+
//
// Utils
//
diff --git a/core/tests/coretests/src/android/graphics/drawable/IconTest.java b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
index b50955b..b7a48c7 100644
--- a/core/tests/coretests/src/android/graphics/drawable/IconTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
@@ -119,13 +119,13 @@
final AdaptiveIconDrawable draw1 = (AdaptiveIconDrawable) im1.loadDrawable(mContext);
final Bitmap test1 = Bitmap.createBitmap(
- (int)(draw1.getIntrinsicWidth() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetPercentage())),
- (int)(draw1.getIntrinsicHeight() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetPercentage())),
+ (int)(draw1.getIntrinsicWidth() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())),
+ (int)(draw1.getIntrinsicHeight() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())),
Bitmap.Config.ARGB_8888);
draw1.setBounds(0, 0,
- (int) (draw1.getIntrinsicWidth() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetPercentage())),
- (int) (draw1.getIntrinsicHeight() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetPercentage())));
+ (int) (draw1.getIntrinsicWidth() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())),
+ (int) (draw1.getIntrinsicHeight() * (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())));
draw1.draw(new Canvas(test1));
final File dir = getContext().getExternalFilesDir(null);
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/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/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/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index 4b1b0c6..d9a77e7 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -52,12 +52,19 @@
mBuilderPtr = nInitBuilder(lang, variant);
}
- public void freeze() {
+ /**
+ * Finalize the FontFamily creation.
+ *
+ * @return boolean returns false if some error happens in native code, e.g. broken font file is
+ * passed, etc.
+ */
+ public boolean freeze() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen");
}
mNativePtr = nCreateFamily(mBuilderPtr);
mBuilderPtr = 0;
+ return mNativePtr != 0;
}
public void abortCreation() {
@@ -143,6 +150,25 @@
isItalic);
}
+ /**
+ * Allow creating unsupported FontFamily.
+ *
+ * For compatibility reasons, we still need to create a FontFamily object even if Minikin failed
+ * to find any usable 'cmap' table for some reasons, e.g. broken 'cmap' table, no 'cmap' table
+ * encoded with Unicode code points, etc. Without calling this method, the freeze() method will
+ * return null if Minikin fails to find any usable 'cmap' table. By calling this method, the
+ * freeze() won't fail and will create an empty FontFamily. This empty FontFamily is placed at
+ * the top of the fallback chain but is never used. if we don't create this empty FontFamily
+ * and put it at top, bad things (performance regressions, unexpected glyph selection) will
+ * happen.
+ */
+ public void allowUnsupportedFont() {
+ if (mBuilderPtr == 0) {
+ throw new IllegalStateException("Unable to allow unsupported font.");
+ }
+ nAllowUnsupportedFont(mBuilderPtr);
+ }
+
// TODO: Remove once internal user stop using private API.
private static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex) {
return nAddFont(builderPtr, font, ttcIndex, -1, -1);
@@ -154,6 +180,9 @@
private static native long nCreateFamily(long mBuilderPtr);
@CriticalNative
+ private static native void nAllowUnsupportedFont(long builderPtr);
+
+ @CriticalNative
private static native void nAbort(long mBuilderPtr);
@CriticalNative
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 395dc07..2aca782 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -34,6 +34,7 @@
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;
@@ -107,6 +108,7 @@
/**
* Cache for Typeface objects dynamically loaded from assets. Currently max size is 16.
*/
+ @GuardedBy("sLock")
private static final LruCache<String, Typeface> sDynamicTypefaceCache = new LruCache<>(16);
static Typeface sDefaultTypeface;
@@ -128,6 +130,7 @@
public static final int BOLD_ITALIC = 3;
private int mStyle = 0;
+ private int mBaseWeight = 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
@@ -179,7 +182,9 @@
if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */,
0 /* ttcIndex */, RESOLVE_BY_FONT_TABLE /* weight */,
RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
- fontFamily.freeze();
+ if (!fontFamily.freeze()) {
+ return null;
+ }
FontFamily[] families = {fontFamily};
typeface = createFromFamiliesWithDefault(families);
sDynamicTypefaceCache.put(key, typeface);
@@ -240,6 +245,10 @@
return null;
}
}
+ // Due to backward compatibility, even if the font is not supported by our font stack,
+ // we need to place the empty font at the first place. The typeface with empty font
+ // behaves different from default typeface especially in fallback font selection.
+ fontFamily.allowUnsupportedFont();
fontFamily.freeze();
FontFamily[] familyChain = { fontFamily };
typeface = createFromFamiliesWithDefault(familyChain);
@@ -291,6 +300,7 @@
* request. May not be null.
* @param callback A callback that will be triggered when results are obtained. May not be null.
*/
+ @Deprecated
public static void create(@NonNull FontRequest request, @NonNull FontRequestCallback callback) {
// Check the cache first
// TODO: would the developer want to avoid a cache hit and always ask for the freshest
@@ -391,7 +401,11 @@
IoUtils.closeQuietly(fd);
}
}
- fontFamily.freeze();
+ if (!fontFamily.freeze()) {
+ callback.onTypefaceRequestFailed(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
+ return;
+ }
Typeface typeface = Typeface.createFromFamiliesWithDefault(new FontFamily[] { fontFamily });
synchronized (sDynamicTypefaceCache) {
String key = createProviderUid(request.getProviderAuthority(), request.getQuery());
@@ -403,6 +417,7 @@
/**
* Interface used to receive asynchronously fetched typefaces.
*/
+ @Deprecated
public interface FontRequestCallback {
/**
* Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
@@ -509,6 +524,10 @@
* </p>
*/
public static final class Builder {
+ /** @hide */
+ public static final int NORMAL_WEIGHT = 400;
+ /** @hide */
+ public static final int BOLD_WEIGHT = 700;
private int mTtcIndex;
private FontVariationAxis[] mAxes;
@@ -517,6 +536,11 @@
private String mPath;
private FileDescriptor mFd;
+ private FontsContract.FontInfo[] mFonts;
+ private Map<Uri, ByteBuffer> mFontBuffers;
+
+ private String mFallbackFamilyName;
+
private int mWeight = RESOLVE_BY_FONT_TABLE;
private int mItalic = RESOLVE_BY_FONT_TABLE;
@@ -559,6 +583,25 @@
}
/**
+ * 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.
*
* Tells the system the weight of the given font. If not provided, the system will resolve
@@ -590,6 +633,10 @@
* collection, do not call this method or specify 0.
*/
public Builder setTtcIndex(@IntRange(from = 0) int ttcIndex) {
+ if (mFonts != null) {
+ throw new IllegalArgumentException(
+ "TTC index can not be specified for FontResult source.");
+ }
mTtcIndex = ttcIndex;
return this;
}
@@ -603,6 +650,13 @@
*/
public Builder setFontVariationSettings(@Nullable String variationSettings)
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.");
+ }
mAxes = FontVariationAxis.fromFontVariationSettings(variationSettings);
return this;
}
@@ -613,11 +667,45 @@
* @param axes An array of font variation axis tag-value pairs.
*/
public Builder setFontVariationSettings(@Nullable FontVariationAxis[] axes) {
+ 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.");
+ }
mAxes = axes;
return this;
}
/**
+ * Sets a fallback family name.
+ *
+ * By specifying a fallback family name, a fallback Typeface will be returned if the
+ * {@link #build} method fails to create a Typeface from the provided font. The fallback
+ * family will be resolved with the provided weight and italic information specified by
+ * {@link #setWeight} and {@link #setItalic}.
+ *
+ * If {@link #setWeight} is not called, the fallback family keeps the default weight.
+ * Similary, if {@link #setItalic} is not called, the fallback family keeps the default
+ * italic information. For example, calling {@code builder.setFallback("sans-serif-light")}
+ * is equivalent to calling {@code builder.setFallback("sans-serif").setWeight(300)} in
+ * terms of fallback. The default weight and italic information are overridden by calling
+ * {@link #setWeight} and {@link #setItalic}. For example, if a Typeface is constructed
+ * using {@code builder.setFallback("sans-serif-light").setWeight(700)}, the fallback text
+ * will render as sans serif bold.
+ *
+ * @param familyName A family name to be used for fallback if the provided font can not be
+ * used. By passing {@code null}, build() returns {@code null}.
+ * If {@link #setFallback} is not called on the builder, {@code null}
+ * is assumed.
+ */
+ public Builder setFallback(@Nullable String familyName) {
+ mFallbackFamilyName = familyName;
+ return this;
+ }
+
+ /**
* Creates a unique id for a given AssetManager and asset path.
*
* @param mgr AssetManager instance
@@ -649,6 +737,54 @@
return builder.toString();
}
+ private static final Object sLock = new Object();
+ // TODO: Unify with Typeface.sTypefaceCache.
+ @GuardedBy("sLock")
+ private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache =
+ new LongSparseArray<>(3);
+
+ private Typeface resolveFallbackTypeface() {
+ if (mFallbackFamilyName == null) {
+ return null;
+ }
+
+ Typeface base = sSystemFontMap.get(mFallbackFamilyName);
+ if (base == null) {
+ base = sDefaultTypeface;
+ }
+
+ if (mWeight == RESOLVE_BY_FONT_TABLE && mItalic == RESOLVE_BY_FONT_TABLE) {
+ return base;
+ }
+
+ final int weight = (mWeight == RESOLVE_BY_FONT_TABLE) ? base.mBaseWeight : mWeight;
+ final boolean italic =
+ (mItalic == RESOLVE_BY_FONT_TABLE) ? (base.mStyle & ITALIC) != 0 : mItalic == 1;
+ final int key = weight << 1 | (italic ? 1 : 0);
+
+ Typeface typeface;
+ synchronized(sLock) {
+ SparseArray<Typeface> innerCache = sTypefaceCache.get(base.native_instance);
+ if (innerCache != null) {
+ typeface = innerCache.get(key);
+ if (typeface != null) {
+ return typeface;
+ }
+ }
+
+ typeface = new Typeface(
+ nativeCreateFromTypefaceWithExactStyle(
+ base.native_instance, weight, italic));
+
+ if (innerCache == null) {
+ innerCache = new SparseArray<>(4); // [regular, bold] x [upright, italic]
+ sTypefaceCache.put(base.native_instance, innerCache);
+ }
+ innerCache.put(key, typeface);
+ }
+ return typeface;
+ }
+
/**
* Generates new Typeface from specified configuration.
*
@@ -664,26 +800,30 @@
final FontFamily fontFamily = new FontFamily();
if (!fontFamily.addFontFromBuffer(buffer, mTtcIndex, mAxes, mWeight, mItalic)) {
fontFamily.abortCreation();
- return null;
+ return resolveFallbackTypeface();
}
- fontFamily.freeze();
+ if (!fontFamily.freeze()) {
+ return resolveFallbackTypeface();
+ }
FontFamily[] families = { fontFamily };
return createFromFamiliesWithDefault(families);
} catch (IOException e) {
- return null;
+ return resolveFallbackTypeface();
}
} else if (mAssetManager != null) { // set source by setSourceFromAsset()
final String key = createAssetUid(mAssetManager, mPath, mTtcIndex, mAxes);
- synchronized (sDynamicTypefaceCache) {
+ synchronized (sLock) {
Typeface typeface = sDynamicTypefaceCache.get(key);
if (typeface != null) return typeface;
final FontFamily fontFamily = new FontFamily();
if (!fontFamily.addFontFromAssetManager(mAssetManager, mPath, mTtcIndex,
true /* isAsset */, mTtcIndex, mWeight, mItalic, mAxes)) {
fontFamily.abortCreation();
- return null;
+ return resolveFallbackTypeface();
}
- fontFamily.freeze();
+ if (!fontFamily.freeze()) {
+ return resolveFallbackTypeface();
+ }
FontFamily[] families = { fontFamily };
typeface = createFromFamiliesWithDefault(families);
sDynamicTypefaceCache.put(key, typeface);
@@ -693,6 +833,34 @@
final FontFamily fontFamily = new FontFamily();
if (!fontFamily.addFont(mPath, mTtcIndex, mAxes, mWeight, mItalic)) {
fontFamily.abortCreation();
+ return resolveFallbackTypeface();
+ }
+ if (!fontFamily.freeze()) {
+ return resolveFallbackTypeface();
+ }
+ FontFamily[] families = { fontFamily };
+ return createFromFamiliesWithDefault(families);
+ } 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();
@@ -796,12 +964,34 @@
throw new NullPointerException(); // for backward compatibility
}
if (sFallbackFonts != null) {
- Typeface typeface = new Builder(mgr, path).build();
- if (typeface != null) {
- return typeface;
+ synchronized (sLock) {
+ Typeface typeface = new Builder(mgr, path).build();
+ if (typeface != null) return typeface;
+
+ final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
+ null /* axes */);
+ typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) return typeface;
+
+ final FontFamily fontFamily = new FontFamily();
+ if (fontFamily.addFontFromAssetManager(mgr, path, 0, true /* isAsset */,
+ 0 /* ttc index */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
+ null /* axes */)) {
+ // Due to backward compatibility, even if the font is not supported by our font
+ // stack, we need to place the empty font at the first place. The typeface with
+ // empty font behaves different from default typeface especially in fallback
+ // font selection.
+ fontFamily.allowUnsupportedFont();
+ fontFamily.freeze();
+ final FontFamily[] families = { fontFamily };
+ typeface = createFromFamiliesWithDefault(families);
+ sDynamicTypefaceCache.put(key, typeface);
+ return typeface;
+ } else {
+ fontFamily.abortCreation();
+ }
}
}
- // For the compatibility reasons, throw runtime exception if failed to create Typeface.
throw new RuntimeException("Font asset not found " + path);
}
@@ -836,17 +1026,20 @@
* @return The new typeface.
*/
public static Typeface createFromFile(@Nullable String path) {
- if (path == null) {
- // For the compatibility reasons, need to throw NPE if the argument is null.
- // See android.graphics.cts.TypefaceTest#testCreateFromFileByFileNameNull
- throw new NullPointerException();
- }
if (sFallbackFonts != null) {
- Typeface typeface = new Builder(path).build();
- if (typeface != null) {
- // For the compatibility reasons, throw runtime exception if failed to create
- // Typeface.
- return typeface;
+ final FontFamily fontFamily = new FontFamily();
+ if (fontFamily.addFont(path, 0 /* ttcIndex */, null /* axes */,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)) {
+ // Due to backward compatibility, even if the font is not supported by our font
+ // stack, we need to place the empty font at the first place. The typeface with
+ // empty font behaves different from default typeface especially in fallback font
+ // selection.
+ fontFamily.allowUnsupportedFont();
+ fontFamily.freeze();
+ FontFamily[] families = { fontFamily };
+ return createFromFamiliesWithDefault(families);
+ } else {
+ fontFamily.abortCreation();
}
}
throw new RuntimeException("Font not found " + path);
@@ -890,6 +1083,7 @@
native_instance = ni;
mStyle = nativeGetStyle(ni);
+ mBaseWeight = nativeGetBaseWeight(ni);
}
private static FontFamily makeFamilyFromParsed(FontConfig.Family family,
@@ -914,7 +1108,11 @@
Log.e(TAG, "Error creating font " + fullPathName + "#" + font.getTtcIndex());
}
}
- fontFamily.freeze();
+ if (!fontFamily.freeze()) {
+ // Treat as system error since reaching here means that a system pre-installed font
+ // can't be used by our font stack.
+ Log.e(TAG, "Unable to load Family: " + family.getName() + ":" + family.getLanguage());
+ }
return fontFamily;
}
@@ -1055,12 +1253,15 @@
}
private static native long nativeCreateFromTypeface(long native_instance, int style);
+ private static native long nativeCreateFromTypefaceWithExactStyle(
+ long native_instance, int weight, boolean italic);
// TODO: clean up: change List<FontVariationAxis> to FontVariationAxis[]
private static native long nativeCreateFromTypefaceWithVariation(
long native_instance, List<FontVariationAxis> axes);
private static native long nativeCreateWeightAlias(long native_instance, int weight);
private static native void nativeUnref(long native_instance);
private static native int nativeGetStyle(long native_instance);
+ private static native int nativeGetBaseWeight(long native_instance);
private static native long nativeCreateFromArray(long[] familyArray);
private static native void nativeSetDefault(long native_instance);
private static native int[] nativeGetSupportedAxes(long native_instance);
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 643c0da..283a3e2 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -29,6 +29,7 @@
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Outline;
@@ -51,12 +52,27 @@
import java.io.IOException;
/**
- * This drawable supports two layers: foreground and background.
- *
- * <p>The layers are clipped when rendering using the mask path defined in the device configuration.
- *
* <p>This class can also be created via XML inflation using <code><adaptive-icon></code> tag
* in addition to dynamic creation.
+ *
+ * <p>This drawable supports two drawable layers: foreground and background. The layers are clipped
+ * when rendering using the mask defined in the device configuration.
+ *
+ * <ul>
+ * <li>Both foreground and background layers should be sized at 108 x 108 dp.</li>
+ * <li>The inner 72 x 72 dp of the icon appears within the masked viewport.</li>
+ * <li>The outer 18 dp on each of the 4 sides of the layers is reserved for use by the system UI
+ * surfaces to create interesting visual effects, such as parallax or pulsing.</li>
+ * </ul>
+ *
+ * Such motion effect is achieved by internally setting the bounds of the foreground and
+ * background layer as following:
+ * <pre>
+ * Rect(getBounds().left - getBounds().getWidth() * #getExtraInsetFraction(),
+ * getBounds().top - getBounds().getHeight() * #getExtraInsetFraction(),
+ * getBounds().right + getBounds().getWidth() * #getExtraInsetFraction(),
+ * getBounds().bottom + getBounds().getHeight() * #getExtraInsetFraction())
+ * </pre>
*/
public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback {
@@ -65,7 +81,11 @@
* @hide
*/
public static final float MASK_SIZE = 100f;
- private static final float SAFEZONE_SCALE = .9f;
+
+ /**
+ * Launcher icons design guideline
+ */
+ private static final float SAFEZONE_SCALE = 72f/66f;
/**
* All four sides of the layers are padded with extra inset so as to provide
@@ -80,7 +100,7 @@
private static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
/**
- * Clip path defined in {@link com.android.internal.R.string.config_icon_mask}.
+ * Clip path defined in R.string.config_icon_mask.
*/
private static Path sMask;
@@ -134,9 +154,10 @@
if (sMask == null) {
sMask = PathParser.createPathFromPathData(
- Resources.getSystem().getString(com.android.internal.R.string.config_icon_mask));
+ Resources.getSystem().getString(R.string.config_icon_mask));
}
- mMask = new Path();
+ mMask = PathParser.createPathFromPathData(
+ Resources.getSystem().getString(R.string.config_icon_mask));
mMaskMatrix = new Matrix();
mCanvas = new Canvas();
mTransparentRegion = new Region();
@@ -212,13 +233,24 @@
* All four sides of the layers are padded with extra inset so as to provide
* extra content to reveal within the clip path when performing affine transformations on the
* layers.
+ *
+ * @see #getForeground() and #getBackground() for more info on how this value is used
+ */
+ public static float getExtraInsetFraction() {
+ return EXTRA_INSET_PERCENTAGE;
+ }
+
+ /**
+ * @hide
*/
public static float getExtraInsetPercentage() {
return EXTRA_INSET_PERCENTAGE;
}
/**
- * Only call this method after bound is set on this drawable.
+ * When called before the bound is set, the returned path is identical to
+ * R.string.config_icon_mask. After the bound is set, the
+ * returned path's computed bound is same as the #getBounds().
*
* @return the mask path object used to clip the drawable
*/
@@ -227,6 +259,10 @@
}
/**
+ * Returns the foreground drawable managed by this class. The bound of this drawable is
+ * extended by {@link #getExtraInsetFraction()} * getBounds().width on left/right sides and by
+ * {@link #getExtraInsetFraction()} * getBounds().height on top/bottom sides.
+ *
* @return the foreground drawable managed by this drawable
*/
public Drawable getForeground() {
@@ -234,6 +270,10 @@
}
/**
+ * Returns the foreground drawable managed by this class. The bound of this drawable is
+ * extended by {@link #getExtraInsetFraction()} * getBounds().width on left/right sides and by
+ * {@link #getExtraInsetFraction()} * getBounds().height on top/bottom sides.
+ *
* @return the background drawable managed by this drawable
*/
public Drawable getBackground() {
@@ -293,10 +333,15 @@
mMaskBitmap = Bitmap.createBitmap(b.width(), b.height(), Bitmap.Config.ALPHA_8);
mLayersBitmap = Bitmap.createBitmap(b.width(), b.height(), Bitmap.Config.ARGB_8888);
}
+ // mMaskBitmap bound [0, w] x [0, h]
mCanvas.setBitmap(mMaskBitmap);
mPaint.setShader(null);
mCanvas.drawPath(mMask, mPaint);
+ // mMask bound [left, top, right, bottom]
+ mMaskMatrix.postTranslate(b.left, b.top);
+ mMask.reset();
+ sMask.transform(mMaskMatrix, mMask);
// reset everything that depends on the view bounds
mTransparentRegion.setEmpty();
mLayersShader = null;
@@ -309,6 +354,7 @@
}
if (mLayersShader == null) {
mCanvas.setBitmap(mLayersBitmap);
+ mCanvas.drawColor(Color.BLACK);
for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
if (mLayerState.mChildren[i] == null) {
continue;
@@ -728,6 +774,12 @@
return mLayerState.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mLayerState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] state) {
boolean changed = false;
@@ -1035,6 +1087,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..34da928 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -17,6 +17,8 @@
package android.graphics.drawable;
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;
@@ -32,6 +34,7 @@
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
+import android.graphics.Xfermode;
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
@@ -306,6 +309,16 @@
invalidateSelf();
}
+ /**
+ * @hide
+ */
+ @Override
+ @TestApi
+ public void setXfermode(@Nullable Xfermode mode) {
+ mShapeState.mPaint.setXfermode(mode);
+ invalidateSelf();
+ }
+
@Override
public int getOpacity() {
if (mShapeState.mShape == null) {
@@ -352,6 +365,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/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index c1cad7d..ed6e522 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -23,6 +23,7 @@
#include "hwui/MinikinUtils.h"
#include "pipeline/skia/AnimatedDrawables.h"
+#include <SkCanvasStateUtils.h>
#include <SkColorSpaceXformCanvas.h>
#include <SkDrawable.h>
#include <SkDeque.h>
@@ -411,6 +412,30 @@
}
// ----------------------------------------------------------------------------
+// Canvas state operations: Capture
+// ----------------------------------------------------------------------------
+
+SkCanvasState* SkiaCanvas::captureCanvasState() const {
+ SkCanvas* canvas = mCanvas;
+ if (mCanvasOwned) {
+ // Important to use the underlying SkCanvas, not the wrapper.
+ canvas = mCanvasOwned.get();
+ }
+
+ // Workarounds for http://crbug.com/271096: SW draw only supports
+ // translate & scale transforms, and a simple rectangular clip.
+ // (This also avoids significant wasted time in calling
+ // SkCanvasStateUtils::CaptureCanvasState when the clip is complex).
+ if (!canvas->isClipRect() ||
+ (canvas->getTotalMatrix().getType() &
+ ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))) {
+ return nullptr;
+ }
+
+ return SkCanvasStateUtils::CaptureCanvasState(canvas);
+}
+
+// ----------------------------------------------------------------------------
// Canvas draw operations
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 13f979c..aeecafa 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -102,6 +102,8 @@
virtual SkDrawFilter* getDrawFilter() override;
virtual void setDrawFilter(SkDrawFilter* drawFilter) override;
+ virtual SkCanvasState* captureCanvasState() const override;
+
virtual void drawColor(int color, SkBlendMode mode) override;
virtual void drawPaint(const SkPaint& paint) override;
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index ed32832..86af678 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -27,6 +27,8 @@
#include <SkCanvas.h>
#include <SkMatrix.h>
+class SkCanvasState;
+
namespace minikin {
class Layout;
}
@@ -200,6 +202,9 @@
virtual SkDrawFilter* getDrawFilter() = 0;
virtual void setDrawFilter(SkDrawFilter* drawFilter) = 0;
+ // WebView only
+ virtual SkCanvasState* captureCanvasState() const { return nullptr; }
+
// ----------------------------------------------------------------------------
// Canvas draw operations
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index 4b8575a..86709ee 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -71,6 +71,18 @@
return result;
}
+Typeface* Typeface::createFromTypefaceWithStyle(Typeface* base, int weight, bool italic) {
+ Typeface* resolvedFace = Typeface::resolveDefault(base);
+ Typeface* result = new Typeface();
+ if (result != nullptr) {
+ result->fFontCollection = resolvedFace->fFontCollection;
+ result->fBaseWeight = weight;
+ result->fStyle = minikin::FontStyle(weight / 100, italic);
+ result->fSkiaStyle = resolvedFace->fSkiaStyle;
+ }
+ return result;
+}
+
Typeface* Typeface::createFromTypefaceWithVariation(Typeface* src,
const std::vector<minikin::FontVariation>& variations) {
Typeface* resolvedFace = Typeface::resolveDefault(src);
diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h
index 19a4f6c5..27ee4a2 100644
--- a/libs/hwui/hwui/Typeface.h
+++ b/libs/hwui/hwui/Typeface.h
@@ -42,6 +42,8 @@
static Typeface* createFromTypeface(Typeface* src, SkTypeface::Style style);
+ static Typeface* createFromTypefaceWithStyle(Typeface* base, int weight, bool italic);
+
static Typeface* createFromTypefaceWithVariation(Typeface* src,
const std::vector<minikin::FontVariation>& variations);
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index 44476af..0d1eba4 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
#include <RecordingCanvas.h>
#include <SkBlurDrawLooper.h>
+#include <SkCanvasStateUtils.h>
#include <SkPicture.h>
#include <SkPictureRecorder.h>
@@ -128,3 +129,32 @@
canvas.asSkCanvas()->drawPicture(picture);
ASSERT_EQ(0xFF0000FF, *skBitmap.getAddr32(0, 0));
}
+
+TEST(SkiaCanvas, captureCanvasState) {
+ // Create a software canvas.
+ SkImageInfo info = SkImageInfo::Make(1, 1, kN32_SkColorType, kOpaque_SkAlphaType);
+ sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info);
+ SkBitmap skBitmap;
+ bitmap->getSkBitmap(&skBitmap);
+ skBitmap.eraseColor(0);
+ SkiaCanvas canvas(skBitmap);
+
+ // Translate, then capture and verify the CanvasState.
+ canvas.translate(1.0f, 1.0f);
+ SkCanvasState* state = canvas.captureCanvasState();
+ ASSERT_NE(state, nullptr);
+ std::unique_ptr<SkCanvas> newCanvas = SkCanvasStateUtils::MakeFromCanvasState(state);
+ ASSERT_NE(newCanvas.get(), nullptr);
+ newCanvas->translate(-1.0f, -1.0f);
+ ASSERT_TRUE(newCanvas->getTotalMatrix().isIdentity());
+ SkCanvasStateUtils::ReleaseCanvasState(state);
+
+ // Create a picture canvas.
+ SkPictureRecorder recorder;
+ SkCanvas* skPicCanvas = recorder.beginRecording(1, 1, NULL, 0);
+ SkiaCanvas picCanvas(skPicCanvas, Canvas::XformToSRGB::kDefer);
+ state = picCanvas.captureCanvasState();
+
+ // Verify that we cannot get the CanvasState.
+ ASSERT_EQ(state, nullptr);
+}
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index aac9727..de85c16 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -670,6 +670,8 @@
* related to L5 will be filled.
*
* <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
+ *
+ * @return the carrier frequency of the signal tracked in Hz.
*/
public float getCarrierFrequencyHz() {
return mCarrierFrequencyHz;
@@ -888,10 +890,10 @@
}
/**
- * Returns {@code true} if {@link #getAutomaticGainControlLevelInDb()} is available,
+ * Returns {@code true} if {@link #getAutomaticGainControlLevelDb()} is available,
* {@code false} otherwise.
*/
- public boolean hasAutomaticGainControlLevelInDb() {
+ public boolean hasAutomaticGainControlLevelDb() {
return isFlagSet(HAS_AUTOMATIC_GAIN_CONTROL);
}
@@ -908,9 +910,9 @@
* components) may also affect the typical output of of this value on any given hardware design
* in an open sky test - the important aspect of this output is that changes in this value are
* indicative of changes on input signal power in the frequency band for this measurement.
- * <p>The value is only available if {@link #hasAutomaticGainControlLevelInDb()} is {@code true}
+ * <p>The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
*/
- public double getAutomaticGainControlLevelInDb() {
+ public double getAutomaticGainControlLevelDb() {
return mAutomaticGainControlLevelInDb;
}
@@ -1064,7 +1066,7 @@
builder.append(String.format(
format,
"AgcLevelDb",
- hasAutomaticGainControlLevelInDb() ? mAutomaticGainControlLevelInDb : null));
+ hasAutomaticGainControlLevelDb() ? mAutomaticGainControlLevelInDb : null));
return builder.toString();
}
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index e90a174..a44bc5b 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -224,7 +224,7 @@
*
* @param satIndex the index of the satellite in the list.
*/
- public boolean hasCarrierFrequency(int satIndex) {
+ public boolean hasCarrierFrequencyHz(int satIndex) {
return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0;
}
@@ -239,7 +239,11 @@
* will be reported for this same satellite, in one all the values related to L1 will be filled,
* and in the other all of the values related to L5 will be filled.
*
- * <p>The value is only available if {@link #hasCarrierFrequency(int satIndex)} is {@code true}.
+ * <p>The value is only available if {@link #hasCarrierFrequencyHz(int satIndex)} is {@code true}.
+ *
+ * @param satIndex the index of the satellite in the list.
+ *
+ * @return the carrier frequency of the signal tracked in Hz.
*/
public float getCarrierFrequencyHz(int satIndex) {
return mCarrierFrequencies[satIndex];
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 4c39c30..6bc5e91 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -242,8 +242,7 @@
}
public boolean getInEmergency() {
- boolean isInEmergencyCallback = Boolean.parseBoolean(
- SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE));
+ boolean isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode();
return mIsInEmergency || isInEmergencyCallback;
}
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/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/PrintSpooler/res/values-km/strings.xml b/packages/PrintSpooler/res/values-km/strings.xml
index 2bc7baa..4409856 100644
--- a/packages/PrintSpooler/res/values-km/strings.xml
+++ b/packages/PrintSpooler/res/values-km/strings.xml
@@ -61,8 +61,8 @@
</plurals>
<string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
<string name="printer_info_desc" msgid="7181988788991581654">"ព័ត៌មានបន្ថែមអំពីម៉ាស៊ីបោះពុម្ពនេះ"</string>
- <string name="notification_channel_progress" msgid="872788690775721436">"កំពុងដំណើរការកិច្ចការបោះពុម្ព"</string>
- <string name="notification_channel_failure" msgid="9042250774797916414">"មិនអាចដំណើរការកិច្ចការបោះពុម្ពបានទេ"</string>
+ <string name="notification_channel_progress" msgid="872788690775721436">"កំពុងបោះពុម្ព"</string>
+ <string name="notification_channel_failure" msgid="9042250774797916414">"មិនអាចបោះពុម្ពបាន"</string>
<string name="could_not_create_file" msgid="3425025039427448443">"មិនអាចបង្កើតឯកសារបានទេ"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"សេវាកម្មបោះពុម្ពមួយចំនួនត្រូវបានបិទដំណើរការ"</string>
<string name="print_searching_for_printers" msgid="6550424555079932867">"ស្វែងរកម៉ាស៊ីនបោះពុម្ព"</string>
diff --git a/packages/PrintSpooler/res/values-pa/strings.xml b/packages/PrintSpooler/res/values-pa/strings.xml
index 6fd021b..d7885ad 100644
--- a/packages/PrintSpooler/res/values-pa/strings.xml
+++ b/packages/PrintSpooler/res/values-pa/strings.xml
@@ -61,8 +61,8 @@
</plurals>
<string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
<string name="printer_info_desc" msgid="7181988788991581654">"ਇਸ ਪ੍ਰਿੰਟਰ ਬਾਰੇ ਹੋਰ ਜਾਣਕਾਰੀ"</string>
- <string name="notification_channel_progress" msgid="872788690775721436">"ਚੱਲ ਰਹੇ ਪ੍ਰਿੰਟ ਕੰਮ"</string>
- <string name="notification_channel_failure" msgid="9042250774797916414">"ਪ੍ਰਿੰਟ ਦੇ ਕੰਮ ਅਸਫਲ ਰਹੇ"</string>
+ <string name="notification_channel_progress" msgid="872788690775721436">"ਚੱਲ ਰਹੇ ਪ੍ਰਿੰਟ ਕਾਰਜ"</string>
+ <string name="notification_channel_failure" msgid="9042250774797916414">"ਅਸਫਲ ਰਹੇ ਪ੍ਰਿੰਟ ਕਾਰਜ"</string>
<string name="could_not_create_file" msgid="3425025039427448443">"ਫ਼ਾਈਲ ਨੂੰ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"ਕੁਝ ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਹਨ"</string>
<string name="print_searching_for_printers" msgid="6550424555079932867">"ਪ੍ਰਿੰਟਰ ਖੋਜ ਰਿਹਾ ਹੈ"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 94c3907..f92cac8 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -125,7 +125,7 @@
<string name="tts_engine_settings_title" msgid="3499112142425680334">"Podešavanja za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
<string name="tts_engine_settings_button" msgid="1030512042040722285">"Pokreni podešavanja mašine"</string>
<string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željena mašina"</string>
- <string name="tts_general_section_title" msgid="4402572014604490502">"Opšte"</string>
+ <string name="tts_general_section_title" msgid="4402572014604490502">"Opšta"</string>
<string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Resetujte visinu tona govora"</string>
<string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Resetujte visinu tona kojom se tekst izgovara na podrazumevanu."</string>
<string-array name="tts_rate_entries">
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index acc0ce0..32a9504 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -316,7 +316,7 @@
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекция на цветове"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
- <string name="power_remaining_duration_only" msgid="845431008899029842">"Оставащо време: Около <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_duration_only" msgid="845431008899029842">"Оставащо време: около <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – около <xliff:g id="TIME">%2$s</xliff:g> оставащо време"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 2b762dfa..444ffbc 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -246,7 +246,7 @@
</string-array>
<string-array name="usb_configuration_titles">
<item msgid="488237561639712799">"Kargatzen"</item>
- <item msgid="5220695614993094977">"MTP (multimedia-elementuak transferitzeko protokoloa)"</item>
+ <item msgid="5220695614993094977">"MTP (multimedia-edukia transferitzeko protokoloa)"</item>
<item msgid="2086000968159047375">"PTP (irudiak transferitzeko protokoloa)"</item>
<item msgid="7398830860950841822">"RNDIS (USB bidezko Ethernet konexioa)"</item>
<item msgid="1718924214939774352">"Audio-iturburua"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 2f92ecd..8f4aec1 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -317,7 +317,7 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
<string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> inguru gelditzen dira"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> gelditzen dira guztiz kargatu arte"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen dira"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 701d80d..875e851 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -254,7 +254,7 @@
<string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Paksa arah tata letak layar RTL untuk semua lokal"</string>
<string name="force_hw_ui" msgid="6426383462520888732">"Paksa perenderan GPU"</string>
<string name="force_hw_ui_summary" msgid="5535991166074861515">"Paksa penggunaan GPU untuk gambar 2d"</string>
- <string name="force_msaa" msgid="7920323238677284387">"Force 4x MSAA"</string>
+ <string name="force_msaa" msgid="7920323238677284387">"Paksa 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9123553203895817537">"Aktifkan 4x MSAA dalam aplikasi OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="505954950474595172">"Debug operasi klip non-kotak"</string>
<string name="track_frame_time" msgid="6146354853663863443">"Penguraian GPU profil"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index f7c95f0..3def72d 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -316,7 +316,7 @@
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correzione del colore"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="power_remaining_duration_only" msgid="845431008899029842">"Quasi scarica. Tempo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_duration_only" msgid="845431008899029842">"Tempo approssimativo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo rimanente alla carica completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ancora circa <xliff:g id="TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 89f82af..9c5c22b 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -168,7 +168,7 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de display sem fios"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar o registo verboso de Wi-Fi"</string>
- <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transm. agressiva de Wi‑Fi p/ rede móvel"</string>
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança brusca de Wi‑Fi para rede móvel"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre a deteção de Wi-Fi em roaming"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 67412cf..c31f12d 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -125,7 +125,7 @@
<string name="tts_engine_settings_title" msgid="3499112142425680334">"Подешавања за <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
<string name="tts_engine_settings_button" msgid="1030512042040722285">"Покрени подешавања машине"</string>
<string name="tts_engine_preference_section_title" msgid="448294500990971413">"Жељена машина"</string>
- <string name="tts_general_section_title" msgid="4402572014604490502">"Опште"</string>
+ <string name="tts_general_section_title" msgid="4402572014604490502">"Општа"</string>
<string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Ресетујте висину тона говора"</string>
<string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Ресетујте висину тона којом се текст изговара на подразумевану."</string>
<string-array name="tts_rate_entries">
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index db590f7..ebed18d 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -317,7 +317,7 @@
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會影響效能。"</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
<string name="power_remaining_duration_only" msgid="845431008899029842">"剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"還需 <xliff:g id="TIME">%1$s</xliff:g>才能完全充電"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g>後就能完全充電"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"尚餘 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 剩餘約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘 <xliff:g id="TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index ad9c769..70cac5e 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -207,7 +207,7 @@
<string name="dev_settings_warning_title" msgid="7244607768088540165">"允許開發設定?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"這些設定僅供開發之用,可能導致您的裝置及裝置中的應用程式毀損或運作異常。"</string>
<string name="verify_apps_over_usb_title" msgid="4177086489869041953">"透過 USB 驗證應用程式"</string>
- <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"透過 ADB/ADT 檢查安裝的應用程式是否出現有害的行為。"</string>
+ <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"檢查透過 ADB/ADT 安裝的應用程式是否具有有害行為。"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"只要停用藍牙絕對音量功能,即可避免在連線到遠端裝置時,發生音量過大或無法控制音量等問題。"</string>
<string name="enable_terminal_title" msgid="95572094356054120">"本機終端機"</string>
<string name="enable_terminal_summary" msgid="67667852659359206">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 34f2822..82ffa68 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -431,6 +431,8 @@
<string name="mobile_data_always_on">Mobile data always active</string>
<!-- Setting Checkbox title for disabling Bluetooth absolute volume -->
<string name="bluetooth_disable_absolute_volume">Disable absolute volume</string>
+ <!-- Setting Checkbox title for enabling Bluetooth inband ringing -->
+ <string name="bluetooth_enable_inband_ringing">Enable in-band ringing</string>
<!-- UI debug setting: Select Bluetooth AVRCP Version -->
<string name="bluetooth_select_avrcp_version_string">Bluetooth AVRCP Version</string>
@@ -512,6 +514,9 @@
<string name="verify_apps_over_usb_summary">Check apps installed via ADB/ADT for harmful behavior.</string>
<!-- Summary of checkbox for disabling Bluetooth absolute volume -->
<string name="bluetooth_disable_absolute_volume_summary">Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control.</string>
+ <!-- Summary of checkbox for enabling Bluetooth inband ringing -->
+ <string name="bluetooth_enable_inband_ringing_summary">Allow ringtones on the phone to be played on Bluetooth headsets</string>
+
<!-- Title of checkbox setting that enables the terminal app. [CHAR LIMIT=32] -->
<string name="enable_terminal_title">Local terminal</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 8833fb8c..02f1162 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -1601,19 +1601,36 @@
}
};
- public static final AppFilter FILTER_OTHER_APPS = new AppFilter() {
+ public static final AppFilter FILTER_MOVIES = new AppFilter() {
@Override
public void init() {
}
@Override
public boolean filterApp(AppEntry entry) {
- boolean isCategorized;
+ boolean isMovieApp;
synchronized(entry) {
- isCategorized = entry.info.category == ApplicationInfo.CATEGORY_AUDIO ||
- entry.info.category == ApplicationInfo.CATEGORY_GAME;
+ isMovieApp = entry.info.category == ApplicationInfo.CATEGORY_VIDEO;
}
- return !isCategorized;
+ return isMovieApp;
}
};
+
+ public static final AppFilter FILTER_OTHER_APPS =
+ new AppFilter() {
+ @Override
+ public void init() {}
+
+ @Override
+ public boolean filterApp(AppEntry entry) {
+ boolean isCategorized;
+ synchronized (entry) {
+ isCategorized =
+ FILTER_AUDIO.filterApp(entry)
+ || FILTER_GAMES.filterApp(entry)
+ || FILTER_MOVIES.filterApp(entry);
+ }
+ return !isCategorized;
+ }
+ };
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 901848a..9e9bc93 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -985,25 +985,32 @@
return false;
}
+ /** Attempt to update the AccessPoint and return true if an update occurred. */
public boolean update(WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
- boolean reorder = false;
+ boolean updated = false;
+ final int oldLevel = getLevel();
if (info != null && isInfoForThisAccessPoint(config, info)) {
- reorder = (mInfo == null);
- mRssi = info.getRssi();
- mInfo = info;
- mNetworkInfo = networkInfo;
- if (mAccessPointListener != null) {
- mAccessPointListener.onAccessPointChanged(this);
+ updated = (mInfo == null);
+ if (mRssi != info.getRssi()) {
+ mRssi = info.getRssi();
+ updated = true;
}
+ mInfo = info;
+ // TODO(b/37289220): compare NetworkInfo states and set updated = true if necessary
+ mNetworkInfo = networkInfo;
} else if (mInfo != null) {
- reorder = true;
+ updated = true;
mInfo = null;
mNetworkInfo = null;
- if (mAccessPointListener != null) {
- mAccessPointListener.onAccessPointChanged(this);
+ }
+ if (updated && mAccessPointListener != null) {
+ mAccessPointListener.onAccessPointChanged(this);
+
+ if (oldLevel != getLevel() /* current level */) {
+ mAccessPointListener.onLevelChanged(this);
}
}
- return reorder;
+ return updated;
}
void update(WifiConfiguration config) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index fc8c42c..f277165 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -203,6 +203,7 @@
mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
mNetworkRequest = new NetworkRequest.Builder()
.clearCapabilities()
@@ -640,20 +641,24 @@
(System.currentTimeMillis() - before) + "ms.");
}
- boolean reorder = false;
+ boolean updated = false;
+ boolean reorder = false; // Only reorder if connected AP was changed
for (int i = mInternalAccessPoints.size() - 1; i >= 0; --i) {
AccessPoint ap = mInternalAccessPoints.get(i);
+ boolean previouslyConnected = ap.isActive();
if (ap.update(connectionConfig, mLastInfo, mLastNetworkInfo)) {
- reorder = true;
+ updated = true;
+ if (previouslyConnected != ap.isActive()) reorder = true;
}
if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) {
reorder = true;
+ updated = true;
}
}
- if (reorder) {
- Collections.sort(mInternalAccessPoints);
- mMainHandler.scheduleAPCopyingAndCloseWriteLock();
- }
+
+ if (reorder) Collections.sort(mInternalAccessPoints);
+
+ if (updated) mMainHandler.scheduleAPCopyingAndCloseWriteLock();
}
/**
@@ -718,6 +723,8 @@
mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info)
.sendToTarget();
mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+ } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
+ mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO);
}
}
};
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
index 6a029f0..c680b2a 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
@@ -174,6 +174,13 @@
}
@Test
+ public void testOtherAppsRejectsLegacyGame() {
+ mEntry.info.flags = ApplicationInfo.FLAG_IS_GAME;
+
+ assertThat(ApplicationsState.FILTER_OTHER_APPS.filterApp(mEntry)).isFalse();
+ }
+
+ @Test
public void testInstantFilterAcceptsInstantApp() {
when(mEntry.info.isInstantApp()).thenReturn(true);
assertThat(ApplicationsState.FILTER_INSTANT.filterApp(mEntry)).isTrue();
@@ -200,4 +207,18 @@
when(mEntry.info.isInstantApp()).thenReturn(true);
assertThat(ApplicationsState.FILTER_DISABLED.filterApp(mEntry)).isFalse();
}
+
+ @Test
+ public void testVideoFilterAcceptsCategorizedVideo() {
+ mEntry.info.category = ApplicationInfo.CATEGORY_VIDEO;
+
+ assertThat(ApplicationsState.FILTER_MOVIES.filterApp(mEntry)).isTrue();
+ }
+
+ @Test
+ public void testVideosFilterRejectsNotVideo() {
+ mEntry.info.category = ApplicationInfo.CATEGORY_GAME;
+
+ assertThat(ApplicationsState.FILTER_MOVIES.filterApp(mEntry)).isFalse();
+ }
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/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/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index b71915f..f9e695d 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -23,6 +23,7 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
@@ -100,6 +101,16 @@
private static final byte SCORE_2 = 15;
private static final int BADGE_2 = NetworkBadging.BADGING_HD;
+ private static final int CONNECTED_NETWORK_ID = 123;
+ private static final int CONNECTED_RSSI = -50;
+ private static final WifiInfo CONNECTED_AP_1_INFO = new WifiInfo();
+ static {
+ CONNECTED_AP_1_INFO.setSSID(WifiSsid.createFromAsciiEncoded(SSID_1));
+ CONNECTED_AP_1_INFO.setBSSID(BSSID_1);
+ CONNECTED_AP_1_INFO.setNetworkId(CONNECTED_NETWORK_ID);
+ CONNECTED_AP_1_INFO.setRssi(CONNECTED_RSSI);
+ }
+
@Captor ArgumentCaptor<WifiNetworkScoreCache> mScoreCacheCaptor;
@Mock private ConnectivityManager mockConnectivityManager;
@Mock private NetworkScoreManager mockNetworkScoreManager;
@@ -312,18 +323,12 @@
private WifiTracker createTrackerWithScanResultsAndAccessPoint1Connected()
throws InterruptedException {
- int networkId = 123;
-
- WifiInfo wifiInfo = new WifiInfo();
- wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(SSID_1));
- wifiInfo.setBSSID(BSSID_1);
- wifiInfo.setNetworkId(networkId);
- when(mockWifiManager.getConnectionInfo()).thenReturn(wifiInfo);
+ when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
WifiConfiguration configuration = new WifiConfiguration();
configuration.SSID = SSID_1;
configuration.BSSID = BSSID_1;
- configuration.networkId = networkId;
+ configuration.networkId = CONNECTED_NETWORK_ID;
when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
NetworkInfo networkInfo = new NetworkInfo(
@@ -445,7 +450,8 @@
}
@Test
- public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged() throws InterruptedException {
+ public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged()
+ throws InterruptedException {
WifiTracker tracker = createMockedWifiTracker();
startTracking(tracker);
sendScanResultsAndProcess(tracker);
@@ -463,7 +469,7 @@
@Test
public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
- WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
+ WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
List<AccessPoint> aps = tracker.getAccessPoints();
assertTrue(aps.size() == 2);
assertEquals(aps.get(0).getSsidStr(), SSID_1);
@@ -636,4 +642,28 @@
tracker.forceUpdate();
verify(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class));
}
-}
+
+ @Test
+ public void rssiChangeBroadcastShouldUpdateConnectedAp() throws Exception {
+ WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
+ assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
+
+ WifiConfiguration configuration = new WifiConfiguration();
+ configuration.SSID = SSID_1;
+ configuration.BSSID = BSSID_1;
+ configuration.networkId = CONNECTED_NETWORK_ID;
+ when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
+
+ int newRssi = CONNECTED_RSSI + 10;
+ WifiInfo info = new WifiInfo(CONNECTED_AP_1_INFO);
+ info.setRssi(newRssi);
+ when(mockWifiManager.getConnectionInfo()).thenReturn(info);
+
+ mAccessPointsChangedLatch = new CountDownLatch(1);
+ tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.RSSI_CHANGED_ACTION));
+ assertTrue(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+
+ verify(mockWifiManager, atLeast(2)).getConnectionInfo();
+ assertThat(tracker.getAccessPoints().get(0).getRssi()).isEqualTo(newRssi);
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml
index 3ea22e9..39cba74 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml
@@ -32,10 +32,8 @@
android:id="@+id/carrier_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ style="@style/Keyguard.TextView"
android:ellipsize="marquee"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary"
android:visibility="gone"
androidprv:allCaps="@bool/kg_use_all_caps" />
@@ -46,10 +44,7 @@
android:layout_weight="1"
android:layout_marginTop="@dimen/eca_overlap"
android:text="@*android:string/lockscreen_emergency_call"
- style="?android:attr/buttonBarButtonStyle"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary"
+ style="@style/Keyguard.TextView.EmergencyButton"
android:textAllCaps="@bool/kg_use_all_caps" />
</com.android.keyguard.EmergencyCarrierArea>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml
index 46aa39d..e1bf6cb 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml
@@ -23,11 +23,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
+ style="@style/Keyguard.TextView"
android:id="@+id/keyguard_message_area"
android:singleLine="true"
android:ellipsize="marquee"
- android:textAppearance="?android:attr/textAppearance"
- android:textSize="@dimen/kg_status_line_font_size"
- android:textColor="?android:attr/textColorSecondary"
android:focusable="true" />
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index dede537..53a559f 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -19,6 +19,15 @@
<resources>
<!-- Keyguard PIN pad styles -->
+ <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
+ <item name="android:textColor">@*android:color/primary_device_default_light</item>
+ <item name="android:textSize">@dimen/kg_status_line_font_size</item>
+ </style>
+ <style name="Keyguard.TextView.EmergencyButton" parent="@android:style/DeviceDefault.ButtonBar">
+ <item name="android:textColor">@*android:color/primary_device_default_light</item>
+ <item name="android:textSize">@dimen/kg_status_line_font_size</item>
+ <item name="android:background">@null</item>
+ </style>
<style name="Widget.TextView.NumPadKey" parent="@android:style/Widget.TextView">
<item name="android:singleLine">true</item>
<item name="android:gravity">center_horizontal|center_vertical</item>
diff --git a/packages/SystemUI/res/drawable/ic_data_off.xml b/packages/SystemUI/res/drawable/ic_data_off.xml
new file mode 100644
index 0000000..b97ddae
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_data_off.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M21.6,21.6L10.8,10.9L2.1,2.1L0.8,3.4l3.3,3.3C3.1,8.2 2.5,10.0 2.5,12.0c0.0,5.2 4.3,9.5 9.5,9.5c2.0,0.0 3.8,-0.6 5.3,-1.6l3.0,3.0L21.6,21.6zM9.6,12.2l0.7,0.7L9.6,12.9L9.6,12.2zM13.9,18.6c-0.2,0.2 -0.5,0.2 -0.6,0.0l-2.4,-3.7l1.5,0.0l2.4,2.4L13.9,18.6z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M12.0,2.5c-2.0,0.0 -3.8,0.6 -5.3,1.6l2.5,2.5L10.0,5.4c0.2,-0.2 0.5,-0.2 0.6,0.0L13.0,9.1l-1.4,0.0l2.0,2.0l0.6,0.0l0.0,0.6l5.6,5.6c1.0,-1.5 1.6,-3.3 1.6,-5.3C21.5,6.8 17.2,2.5 12.0,2.5z"
+ android:fillColor="#ffffff"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_on.xml b/packages/SystemUI/res/drawable/ic_data_on.xml
new file mode 100644
index 0000000..a65dc79
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_data_on.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M12.0,12.0m-9.5,0.0a9.5,9.5 0.0,1.0 1.0,19.0 0.0a9.5,9.5 0.0,1.0 1.0,-19.0 0.0
+ M10.6,5.4c-0.2,-0.2 -0.5,-0.2 -0.6,0.0L7.6,9.1l2.0,0.0l0.0,3.8L11.0,12.900001L11.0,9.1l2.0,0.0L10.6,5.4z
+ M13.3,18.6c0.2,0.2 0.5,0.2 0.6,0.0l2.4,-3.7l-2.0,0.0l0.0,-3.8l-1.4,0.0l0.0,3.8l-2.0,0.0L13.3,18.6z"
+ android:fillColor="#ffffff"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_unavailable.xml b/packages/SystemUI/res/drawable/ic_data_unavailable.xml
new file mode 100644
index 0000000..27a7697
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_data_unavailable.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+ M12.0,12.0m-9.5,0.0a9.5,9.5 0.0,1.0 1.0,19.0 0.0a9.5,9.5 0.0,1.0 1.0,-19.0 0.0
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M12.0,2.5c-5.246705,0.0 -9.5,4.253295 -9.5,9.5 0.0,5.246705 4.253295,9.5 9.5,9.5 2.771732,0.0 5.263364,-1.200342 7.0,-3.09375l0.0,-0.21875 0.0,-7.5 0.0,-1.0 1.0,0.0 1.1875,0.0C20.148497,5.5674677 16.442669,2.5 12.0,2.5zm9.1875,7.1875c-14.125,9.541667 -7.0625,4.770833 0.0,0.0z
+ M10.6,5.4C10.4,5.2 10.1,5.2 10.0,5.4L7.6,9.1l2.0,0.0l0.0,3.8L11.0,12.900001L11.0,9.1l2.0,0.0L10.6,5.4z
+ M13.3,18.6c0.2,0.2 0.5,0.2 0.6,0.0l2.4,-3.7l-2.0,0.0l0.0,-3.8l-1.4,0.0l0.0,3.8l-2.0,0.0l2.4,3.7z
+ M21.7,24.0c-0.5,0.0 -0.8,-0.1 -1.1,-0.4c-0.3,-0.3 -0.4,-0.6 -0.4,-1.0c0.0,-0.4 0.1,-0.8 0.4,-1.0c0.3,-0.3 0.7,-0.4 1.1,-0.4s0.8,0.1 1.1,0.4c0.3,0.3 0.4,0.6 0.4,1.0c0.0,0.4 -0.1,0.7 -0.4,1.0
+ C22.6,23.8 22.2,24 21.7,24z
+ M20.4,19.7l0.0,-8.5L23.0,11.2l0.0,8.5L20.4,19.7z
+ "
+ android:fillType="evenOdd"
+ android:fillColor="#231F20"/>
+</vector>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 74047cd..5859838 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is af"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth is af"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Moenie steur nie is af"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\'n Outomatiese reël (<xliff:g id="ID_1">%s</xliff:g>) het Moenie steur nie aangeskakel. Hou huidige instellings?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\'n Program (<xliff:g id="ID_1">%s</xliff:g>) het Moenie steur nie aangeskakel. Hou huidige instellings?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\'n Outomatiese reël of \'n program het Moenie steur nie aangeskakel. Hou huidige instellings?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Tot <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Hou"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Vervang"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 9ef3792..97b8317 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ጠፍቷል"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ብሉቱዝ ጠፍቷል"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"አትረብሽ ጠፍቷል"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"አትረብሽ በአንድ ራስ-ሰር ደንብ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል። የአሁኖቹ ቅንብሮች ይቀመጡ?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"አትረብሽ በአንድ መተግበሪያ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል። የአሁኖቹ ቅንብሮች ይቀመጡ?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"አትረብሽ በአንድ ራስ-ሰር ደንብ ወይም መተግበሪያ በርቷል። የአሁኖቹ ቅንብሮች ይቀመጡ?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"እስከ <xliff:g id="ID_1">%s</xliff:g> ድረስ"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"አቆይ"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"ተካ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 31621a4..f646dfa 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -758,9 +758,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"تم إيقاف شبكة Wi-Fi"</string>
<string name="bt_is_off" msgid="2640685272289706392">"تم إيقاف البلوتوث."</string>
<string name="dnd_is_off" msgid="6167780215212497572">"تم إيقاف وضع \"الرجاء عدم الإزعاج\""</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"تم تشغيل وضع \"الرجاء عدم الإزعاج\" بواسطة قاعدة تلقائية (<xliff:g id="ID_1">%s</xliff:g>). هل تريد الإبقاء على الإعدادات الحالية؟"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"تم تشغيل وضع \"الرجاء عدم الإزعاج\" بواسطة تطبيق (<xliff:g id="ID_1">%s</xliff:g>). هل تريد الإبقاء على الإعدادات الحالية؟"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"تم تشغيل وضع \"الرجاء عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق. هل تريد الإبقاء على الإعدادات الحالية؟"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"حتى <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"الإبقاء على الإعدادات"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"استبدال"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 5d485d5..3223aa7 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batareya doldurulur, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> faiz."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Sistem parametrləri"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirişlər."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Bütün bildirişlərə baxın"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Bildirişi təmizlə."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktivdir."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS əldə edilir."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi deaktivdir"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth deaktivdir"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"Narahat Etməyin\" deaktivdir"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) avtomatik qaydası tərəfindən aktiv edildi. Cari ayarlar saxlanılsın?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\"Narahat etməyin\" (<xliff:g id="ID_1">%s</xliff:g>) tətbiqi tərəfindən aktiv edildi. Cari ayarlar saxlanılsın?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\"Narahat etməyin\" rejimi avtomatik qayda və ya tətbiq tərəfindən aktiv edildi. Cari ayarlar saxlanılsın?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> vaxtına qədər"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Saxlayın"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Əvəz edin"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 259e3ab..1a1883c 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -746,9 +746,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Režim Ne uznemiravaj je isključen"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj. Želite li da zadržite aktuelna podešavanja?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je uključila režim Ne uznemiravaj. Želite li da zadržite aktuelna podešavanja?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Automatsko pravilo ili aplikacija su uključili režim Ne uznemiravaj. Želite li da zadržite aktuelna podešavanja?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zameni"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index e9b2c85..59aa605 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -752,9 +752,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi выключаны"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth выключаны"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Рэжым \"Не турбаваць\" выключаны"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам (<xliff:g id="ID_1">%s</xliff:g>). Пакінуць бягучыя налады?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Рэжым \"Не турбаваць\" быў уключаны праграмай (<xliff:g id="ID_1">%s</xliff:g>). Пакінуць бягучыя налады?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам ці праграмай. Пакінуць бягучыя налады?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Да <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Пакінуць"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замяніць"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ac940df..a9bcf11 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Функцията за Wi‑Fi е изключена"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Функцията за Bluetooth е изключена"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Режимът „Не безпокойте“ е изключен"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Режимът „Не безпокойте“ бе включен от автоматично правило (<xliff:g id="ID_1">%s</xliff:g>). Искате ли да запазите текущите настройки?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Режимът „Не безпокойте“ бе включен от приложение (<xliff:g id="ID_1">%s</xliff:g>). Искате ли да запазите текущите настройки?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Режимът „Не безпокойте“ бе включен от автоматично правило или от приложение. Искате ли да запазите текущите настройки?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"До <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Запазване"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замяна"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 056ab31..c0f6f51 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -743,9 +743,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"ওয়াই ফাই বন্ধ আছে"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ব্লুটুথ বন্ধ আছে"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"বিরক্ত করবেন না বিকল্পটি বন্ধ আছে"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"বিরক্ত করবেন না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম (<xliff:g id="ID_1">%s</xliff:g>) এর দ্বারা চালু করা হয়েছে। বর্তমান সেটিংস রাখতে চান?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"বিরক্ত করবেন না বিকল্পটি একটি অ্যাপ (<xliff:g id="ID_1">%s</xliff:g>) এর দ্বারা চালু করা হয়েছে। বর্তমান সেটিংস রাখতে চান?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"বিরক্ত করবেন না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম বা অ্যাপের দ্বারা চালু করা হয়েছে। বর্তমান সেটিংস রাখতে চান?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> পর্যন্ত"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"রাখুন"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"বদলে দিন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 49eee24..2ea22ec 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -748,9 +748,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi veza je isključena"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Opcija Ne ometaj je isključena"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) uključilo je opciju Ne ometaj. Želite li zadržati trenutne postavke?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) uključila je opciju Ne ometaj. Želite li zadržati trenutne postavke?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Automatsko pravilo ili aplikacija uključili su opciju Ne ometaj. Želite li zadržati trenutne postavke?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index d95c991..1b211d2 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"La bateria s\'està carregant, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Configuració del sistema."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacions."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Mostra totes les notificacions"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Esborra la notificació."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activat."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"S\'està adquirint el GPS."</string>
@@ -467,7 +466,7 @@
<string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona el teu perfil professional. El perfil està connectat a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador."</string>
<string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona el teu perfil professional. El perfil està connectat a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nTambé estàs connectat a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pot supervisar la teva activitat personal a la xarxa."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"El dispositiu continuarà bloquejat fins que no el desbloquegis manualment."</string>
- <string name="hidden_notifications_title" msgid="7139628534207443290">"Obtén notificacions més ràpidament"</string>
+ <string name="hidden_notifications_title" msgid="7139628534207443290">"Rep notificacions més ràpidament"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Mostra-les abans de desbloquejar"</string>
<string name="hidden_notifications_cancel" msgid="3690709735122344913">"No"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"Configura"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"La Wi-Fi està desactivada"</string>
<string name="bt_is_off" msgid="2640685272289706392">"El Bluetooth està desactivat"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"El mode No molestis està desactivat"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Una regla automàtica (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis. Vols conservar la configuració actual?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Una aplicació (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis. Vols conservar la configuració actual?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Una regla automàtica o una aplicació han activat el mode No molestis. Vols conservar la configuració actual?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Fins a les <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Conserva"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substitueix"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index af27f4a..68cb7e8 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -752,9 +752,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je vypnuta"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je vypnuto"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Režim Nerušit je vypnut"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Režim Nerušit byl zapnut automatickým pravidlem (<xliff:g id="ID_1">%s</xliff:g>). Ponechat aktuální nastavení?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Režim Nerušit byl zapnut aplikací (<xliff:g id="ID_1">%s</xliff:g>). Ponechat aktuální nastavení?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Režim Nerušit byl zapnut automatickým pravidlem nebo aplikací. Ponechat aktuální nastavení?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zachovat"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradit"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 330265b..e304b54 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet oplades. <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Systemindstillinger."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Underretninger."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Se alle underretninger"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Ryd underretning."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiveret."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS samler data."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi er slået fra"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth er slået fra"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Forstyr ikke er slået fra"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Forstyr ikke blev aktiveret af en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>). Vil du beholde de nuværende indstillinger?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Forstyr ikke blev aktiveret af en app (<xliff:g id="ID_1">%s</xliff:g>). Vil du beholde de nuværende indstillinger?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Forstyr ikke blev aktiveret af en automatisk regel eller en app. Vil du beholde de nuværende indstillinger?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Indtil <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behold"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Erstat"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 434ce6d..9780181 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Systemeinstellungen"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Benachrichtigungen"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Alle Benachrichtigungen ansehen"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Benachrichtigung löschen"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiviert"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS-Signal abrufen"</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"WLAN ist deaktiviert"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth ist deaktiviert"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"Nicht stören\" ist deaktiviert"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\"Nicht stören\" wurde von einer automatischen Regel aktiviert (<xliff:g id="ID_1">%s</xliff:g>). Aktuelle Einstellungen beibehalten?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\"Nicht stören\" wurde von einer App aktiviert (<xliff:g id="ID_1">%s</xliff:g>). Aktuelle Einstellungen beibehalten?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\"Nicht stören\" wurde von einer automatischen Regel oder einer App aktiviert. Aktuelle Einstellungen beibehalten?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Bis <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Beibehalten"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ersetzen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 785f3db..710c455 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Το Wi-Fi είναι ανενεργό"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Το Bluetooth είναι ανενεργό"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Η λειτουργία \"Μην ενοχλείτε\" είναι ανενεργή"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα (<xliff:g id="ID_1">%s</xliff:g>). Διατήρηση τρεχουσών ρυθμίσεων;"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από μια εφαρμογή (<xliff:g id="ID_1">%s</xliff:g>). Διατήρηση τρεχουσών ρυθμίσεων;"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα ή μια εφαρμογή. Διατήρηση τρεχουσών ρυθμίσεων;"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Έως τις <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Διατήρηση"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Αντικατάσταση"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 79f924b..723be15 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Do Not Disturb is off"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>). Keep current settings?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>). Keep current settings?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Do Not Disturb was turned on by an automatic rule or app. Keep current settings?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Until <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Keep"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 79f924b..723be15 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Do Not Disturb is off"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>). Keep current settings?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>). Keep current settings?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Do Not Disturb was turned on by an automatic rule or app. Keep current settings?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Until <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Keep"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 79f924b..723be15 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth is off"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Do Not Disturb is off"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>). Keep current settings?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>). Keep current settings?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Do Not Disturb was turned on by an automatic rule or app. Keep current settings?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Until <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Keep"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 9090fa0..16e2549 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -744,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desactivado"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth desactivado"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"No interrumpir desactivado"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Una regla automática activó No interrumpir (<xliff:g id="ID_1">%s</xliff:g>). ¿Deseas mantener la configuración actual?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Una app (<xliff:g id="ID_1">%s</xliff:g>) activó No interrumpir. ¿Deseas mantener la configuración actual?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Una app o regla automática activó No interrumpir. ¿Deseas mantener la configuración actual?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Hasta la(s) <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Mantener"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index f15b5c1..2c21bae 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -744,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desactivado"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth desactivado"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"No molestar está desactivado"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Una regla automática (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar. ¿Quieres conservar esta configuración?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Una aplicación (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar. ¿Quieres conservar esta configuración?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Una aplicación o una regla automática han activado No molestar. ¿Quieres conservar esta configuración?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Hasta <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Conservar"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f423f8c..fbe6dfc 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -744,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"WiFi on välja lülitatud"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth on välja lülitatud"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Funktsioon Mitte segada on välja lülitatud"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Automaatne reegel lülitas funktsiooni Mitte segada sisse (<xliff:g id="ID_1">%s</xliff:g>). Kas jätta praegused seaded aktiivseks?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Rakendus lülitas funktsiooni Mitte segada sisse (<xliff:g id="ID_1">%s</xliff:g>). Kas jätta praegused seaded aktiivseks?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Automaatne reegel või rakendus lülitas funktsiooni Mitte segada sisse. Kas jätta praegused seaded aktiivseks?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Kuni ajani <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Säilita"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Asenda"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 02c8617..c802e8a 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Sistemaren ezarpenak."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Jakinarazpenak."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ikusi jakinarazpen guztiak"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Garbitu jakinarazpena."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktibatuta."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS seinalea lortzen."</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi konexioa desaktibatuta dago"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth konexioa desaktibatuta dago"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"Ez molestatu\" modua desaktibatuta dago"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\"Ez molestatu\" modua aktibatu du arau automatiko batek (<xliff:g id="ID_1">%s</xliff:g>). Uneko ezarpenak mantendu nahi dituzu?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\"Ez molestatu\" modua aktibatu du aplikazio batek (<xliff:g id="ID_1">%s</xliff:g>). Uneko ezarpenak mantendu nahi dituzu?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\"Ez molestatu\" modua aktibatu du arau automatiko edo aplikazio batek. Uneko ezarpenak mantendu nahi dituzu?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> arte"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Utzi bere horretan"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ordeztu"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0408f71..9c35ddc 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"در حال شارژ باتری، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> درصد"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"تنظیمات سیستم."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"اعلانها."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"دیدن همه اعلانها"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"پاک کردن اعلان"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS فعال شد."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"دستیابی به GPS."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi خاموش است"</string>
<string name="bt_is_off" msgid="2640685272289706392">"بلوتوث خاموش است"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"«مزاحم نشوید» خاموش است"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"قانون خودکاری (<xliff:g id="ID_1">%s</xliff:g>) حالت «مزاحم نشوید» را روشن کرده است. تنظیمات کنونی حفظ شود؟"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"برنامهای (<xliff:g id="ID_1">%s</xliff:g>) حالت «مزاحم نشوید» را روشن کرده است. تنظیمات کنونی حفظ شود؟"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"قانون خودکار یا برنامهای حالت «مزاحم نشوید» را روشن کرده است. تنظیمات کنونی حفظ شود؟"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"تا <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"حفظ شود"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"جایگزین کردن"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index ee01382..a949b8b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi on pois käytöstä"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth ei ole käytössä"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Älä häiritse ‑tila on pois käytöstä"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Automaattinen sääntö otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>). Pidetäänkö nykyiset asetukset?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Sovellus otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>). Pidetäänkö nykyiset asetukset?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Automaattinen sääntö tai sovellus otti käyttöön Älä häiritse ‑tilan. Pidetäänkö nykyiset asetukset?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> asti"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Säilytä"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Korvaa"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 4331edf..ffbd493 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Afficher toutes les notifications"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activé"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Acquisition de données GPS"</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Le Wi-Fi est désactivé"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Le Bluetooth est désactivé"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Le mode Ne pas déranger est désactivé"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Le mode Ne pas déranger a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>). Garder les paramètres actuels?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Le mode Ne pas déranger a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>). Garder les paramètres actuels?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Le mode Ne pas déranger a été activé par une règle automatique ou une application. Garder les paramètres actuels?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Jusqu\'à <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Garder"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 661d2d8..d7f7115 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Afficher toutes les notifications"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activé"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Acquisition de données GPS"</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi désactivé"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth désactivé"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Mode \"Ne pas déranger\" désactivé"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Le mode \"Ne pas déranger\" a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>). Conserver les paramètres actuels ?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Le mode \"Ne pas déranger\" a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>). Conserver les paramètres actuels ?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Le mode \"Ne pas déranger\" a été activé par une règle automatique ou une application. Conserver les paramètres actuels ?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Jusqu\'à <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Conserver"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e10bd20..ec65726 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -744,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"A wifi está desactivada"</string>
<string name="bt_is_off" msgid="2640685272289706392">"O Bluetooth está desactivado"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"O modo Non molestar está desactivado"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Unha norma automática (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar. Queres manter a configuración actual?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Unha aplicación (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar. Queres manter a configuración actual?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Unha aplicación ou norma automática activou o modo Non molestar. Queres manter a configuración actual?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Ata: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituír"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 53d1e1c..3c3681d 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -743,9 +743,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi બંધ છે"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth બંધ છે"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"ખલેલ પાડશો નહીં બંધ છે"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>). વર્તમાન સેટિંગ્સ રાખીએ?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"ખલેલ પાડશો નહીં એક ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું. (<xliff:g id="ID_1">%s</xliff:g>). વર્તમાન સેટિંગ્સ રાખીએ?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ અથવા ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું. વર્તમાન સેટિંગ્સ રાખીએ?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> સુધી"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"રાખો"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"બદલો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 6068dc9..e4c1071 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"वाई-फ़ाई बंद है"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ब्लूटूथ बंद है"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"परेशान न करें बंद है"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"एक ऑटोमैटिक नियम (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था. क्या अभी वाली सेटिंग बनाए रखें?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"एक ऐप्लिकेशन (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था. क्या अभी वाली सेटिंग बनाए रखें?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"एक ऑटोमैटिक नियम या ऐप्लिकेशन ने परेशान न करें को चालू कर दिया था. क्या अभी वाली सेटिंग बनाए रखें?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> तक"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"रखें"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"बदलें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2cced0e..9e138ae 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -746,9 +746,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Način Ne uznemiravaj isključen"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Način Ne uznemiravaj uključen je automatskim pravilom (<xliff:g id="ID_1">%s</xliff:g>). Želite li zadržati trenutačne postavke?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Način Ne uznemiravaj uključila je aplikacija (<xliff:g id="ID_1">%s</xliff:g>). Želite li zadržati trenutačne postavke?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Način Ne uznemiravaj uključen je automatskim pravilom ili ga je uključila aplikacija. Želite li zadržati trenutačne postavke?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index d2e37e9..a34da65 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Akkumulátor töltése folyamatban, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> százalék."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Rendszerbeállítások"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Értesítések"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Összes értesítés megtekintése"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Értesítés törlése"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS engedélyezve."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS lekérése."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"A Wi-Fi ki van kapcsolva"</string>
<string name="bt_is_off" msgid="2640685272289706392">"A Bluetooth ki van kapcsolva"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"A „Ne zavarjanak” mód ki van kapcsolva"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Az egyik automatikus szabály (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot. Megtartja a jelenlegi beállításokat?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Az egyik alkalmazás (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot. Megtartja a jelenlegi beállításokat?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Az egyik alkalmazás vagy automatikus szabály bekapcsolta a „Ne zavarjanak” módot. Megtartja a jelenlegi beállításokat?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Eddig: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Megtartás"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Csere"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 599a774..6635e61 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi-ն անջատված է"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth-ն անջատված է"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Չանհանգստացնելու ռեժիմն անջատված է"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Չանհանգստացնելու ռեժիմն անջատվել է ավտոմատ կանոնի կողմից (<xliff:g id="ID_1">%s</xliff:g>)։ Պահպանե՞լ ընթացիկ կարգավորումները։"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Չանհանգստացնելու ռեժիմն անջատվել է հավելվածի կողմից (<xliff:g id="ID_1">%s</xliff:g>)։ Պահպանե՞լ ընթացիկ կարգավորումները։"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Չանհանգստացնելու ռեժիմն անջատվել է ավտոմատ կանոնի կամ հավելվածի կողմից։ Պահպանե՞լ ընթացիկ կարգավորումները։"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Մինչև <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Պահել"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Փոխարինել"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 8bf0077..6c07944 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi nonaktif"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth nonaktif"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Fitur Jangan Ganggu nonaktif"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Fitur Jangan Ganggu diaktifkan oleh aturan otomatis (<xliff:g id="ID_1">%s</xliff:g>). Simpan setelan saat ini?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Fitur Jangan Ganggu diaktifkan oleh aplikasi (<xliff:g id="ID_1">%s</xliff:g>). Simpan setelan saat ini?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Fitur Jangan Ganggu diaktifkan oleh aplikasi atau aturan otomatis. Simpan setelan saat ini?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Hingga <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Simpan"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ganti"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 3b4899d..57e031d 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Slökkt á Wi-Fi"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Slökkt á Bluetooth"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Slökkt á „Ónáðið ekki“"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Sjálfvirk regla (<xliff:g id="ID_1">%s</xliff:g>) kveikti á „Ónáðið ekki“. Halda núverandi stillingum?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Forrit (<xliff:g id="ID_1">%s</xliff:g>) kveikti á „Ónáðið ekki“. Halda núverandi stillingum?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Sjálfvirk regla eða forrit slökkti á „Ónáðið ekki“. Halda núverandi stillingum?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Þar til <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Halda"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Skipta út"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 23fe502..1aab341 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -744,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi disattivato"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth non attivo"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Funzione Non disturbare disattivata"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"La funzione Non disturbare è stata attivata da una regola automatica (<xliff:g id="ID_1">%s</xliff:g>). Mantenere le impostazioni attuali?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"La funzione Non disturbare è stata attivata da un\'app (<xliff:g id="ID_1">%s</xliff:g>). Mantenere le impostazioni attuali?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"La funzione Non disturbare è stata attivata da una regola automatica o da un\'app. Mantenere le impostazioni attuali?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Fino alle ore <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Mantieni"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Sostituisci"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b5a1e67..ab821b6 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -166,8 +166,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"טעינת סוללה, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> אחוז."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"הגדרות מערכת"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"התראות"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"הצגת כל ההודעות"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"נקה התראה"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS מופעל."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"השגת GPS."</string>
@@ -751,9 +750,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi כבוי"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth כבוי"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"מצב \'נא לא להפריע\' כבוי"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"מצב \'נא לא להפריע\' הופעל על ידי כלל אוטומטי (<xliff:g id="ID_1">%s</xliff:g>). האם לשמור את ההגדרות הקיימות?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"מצב \'נא לא להפריע\' הופעל על ידי האפליקציה (<xliff:g id="ID_1">%s</xliff:g>). האם לשמור את ההגדרות הקיימות?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"מצב \'נא לא להפריע\' הופעל על ידי כלל אוטומטי או אפליקציה. האם לשמור את ההגדרות הקיימות?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"עד <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"שמור"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"החלף"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 06f761a..9454d54 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"システム設定。"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"通知をすべて表示"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"通知を消去。"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPSが有効です。"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS取得中です。"</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi は OFF です"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth は OFF です"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"マナーモードは OFF です"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"マナーモードが自動ルール(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。現在の設定を維持しますか?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"マナーモードがアプリ(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。現在の設定を維持しますか?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"マナーモードが自動ルールまたはアプリによって ON になりました。現在の設定を維持しますか?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"終了時間: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"設定を維持"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"設定を変更"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 94884da..5281011 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ბატარეა იტენება, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> პროცენტი."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"სისტემის პარამეტრები."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"შეტყობინებები"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"ყველა შეტყობინების ნახვა"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"შეტყობინებების გასუფთავება."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS გააქტიურდა."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS-ის დადგენა."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi გამორთულია"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth გამორთულია"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"„არ შემაწუხოთ“ რეჟიმი გამორთულია"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"„არ შემაწუხოთ“ ჩართულია ავტომატური წესის მიხედვით (<xliff:g id="ID_1">%s</xliff:g>). გსურთ მიმდინარე პარამეტრების შენარჩუნება?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"„არ შემაწუხოთ“ ჩართულია აპის მიერ (<xliff:g id="ID_1">%s</xliff:g>). გსურთ მიმდინარე პარამეტრების შენარჩუნება?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"„არ შემაწუხოთ“ ჩართულია ავტომატური წესის მიხედვით ან აპის მიერ. გსურთ მიმდინარე პარამეტრების შენარჩუნება?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g>-მდე"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"შენარჩუნება"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"ჩანაცვლება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 970591c..0ae02cc 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi өшірулі"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth өшірулі"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"Мазаламау\" режимі өшірулі"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\"Мазаламау\" режимі (<xliff:g id="ID_1">%s</xliff:g>) автоматты ережесі арқылы қосылды. Ағымдағы параметрлер қалсын ба?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\"Мазаламау\" режимі (<xliff:g id="ID_1">%s</xliff:g>) қолданбасы арқылы қосылды. Ағымдағы параметрлер қалсын ба?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\"Мазаламау\" режимі автоматты ереже немесе қолданба арқылы қосылды. Ағымдағы параметрлер қалсын ба?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> дейін"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Қалсын"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ауыстыру"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index a259301..6545d3a 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"កំពុងសាកថ្ម <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ភាគរយ"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"ការកំណត់ប្រព័ន្ធ។"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"ការជូនដំណឹង។"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"មើលការជូនដំណឹងទាំងអស់"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"សម្អាតការជូនដំណឹង។"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"បានបើក GPS ។"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"ទទួល GPS ។"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi បានបិទ"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ប៊្លូធូសបានបិទ"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"មុខងារកុំរំខានបានបិទ"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"មុខងារកុំរំខានត្រូវបានបើកដោយច្បាប់ស្វ័យប្រវត្តិ (<xliff:g id="ID_1">%s</xliff:g>)។ រក្សាការកំណត់បច្ចុប្បន្ននៅដដែល?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"មុខងារកុំរំខានត្រូវបានបើកដោយកម្មវិធី (<xliff:g id="ID_1">%s</xliff:g>)។ រក្សាការកំណត់បច្ចុប្បន្ននៅដដែល?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"មុខងារកុំរំខានត្រូវបានបើកដោយច្បាប់ស្វ័យប្រវត្តិ ឬកម្មវិធី។ រក្សាការកំណត់បច្ចុប្បន្ននៅដដែល?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"រហូតដល់ <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"រក្សានៅដដែល"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"ជំនួស"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index df7935a..fd3233e 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ಬ್ಯಾಟರಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ಪ್ರತಿಶತ."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"ಸಿಸ್ಟಂ ಸೆಟ್ಟಿಂಗ್ಗಳು."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"ಅಧಿಸೂಚನೆಗಳು."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಿ"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"ಅಧಿಸೂಚನೆ ತೆರವುಗೊಳಿಸು."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ಸಕ್ರಿಯವಾಗಿದೆ."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS ಸ್ವಾಧೀನ."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"ವೈ-ಫೈ ಆಫ್ ಆಗಿದೆ"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ಬ್ಲೂಟೂತ್ ಆಫ್ ಆಗಿದೆ"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆಫ್ ಆಗಿದೆ"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"(<xliff:g id="ID_1">%s</xliff:g>) ಸ್ವಯಂಚಾಲಿತ ನಿಯಮದ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ. ಪ್ರಸ್ತುತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಹಾಗೆಯೇ ಇರಿಸುವುದೇ?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"(<xliff:g id="ID_1">%s</xliff:g>) ಅಪ್ಲಿಕೇಶನ್ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ. ಪ್ರಸ್ತುತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಹಾಗೆಯೇ ಇರಿಸುವುದೇ?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"ಸ್ವಯಂಚಾಲಿತ ನಿಯಮ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ. ಪ್ರಸ್ತುತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಹಾಗೆಯೇ ಇರಿಸುವುದೇ?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> ತನಕ"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"ಇರಿಸಿ"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"ಬದಲಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 4286235..649dd1a 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"시스템 설정"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"알림"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"모든 알림 보기"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"알림 지우기"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS가 사용 설정되었습니다."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS를 가져오는 중입니다."</string>
@@ -275,7 +274,7 @@
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"블루투스"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"블루투스(<xliff:g id="NUMBER">%d</xliff:g>개의 기기)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"블루투스 사용 안함"</string>
- <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"페어링된 기기가 없습니다."</string>
+ <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"페어링된 기기가 없습니다"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"밝기"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"자동 회전"</string>
<string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"화면 자동 회전"</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi가 사용 중지됨"</string>
<string name="bt_is_off" msgid="2640685272289706392">"블루투스가 사용 중지됨"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"알림 일시중지가 사용 중지됨"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"알림 일시중지가 자동 규칙(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다. 현재 설정을 유지하시겠습니까?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"알림 일시중지가 앱(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다. 현재 설정을 유지하시겠습니까?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"알림 일시중지가 자동 규칙 또는 앱에 의해 사용 설정되었습니다. 현재 설정을 유지하시겠습니까?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g>까지"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"유지"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"바꾸기"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 174872d..53b46f9 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi өчүк"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth өчүк"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"Тынчымды алба\" режими өчүк"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Автоматтык эреже \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>). Учурдагы жөндөөлөр сакталсынбы?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Колдонмо \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>). Учурдагы жөндөөлөр сакталсынбы?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Автоматтык эреже же колдонмо \"Тынчымды алба\" режимин күйгүздү. Учурдагы жөндөөлөр сакталсынбы?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> чейин"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Ушундай калтыруу"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Алмаштыруу"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index afac247..72fc0c6 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ປິດຢູ່"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth ປິດຢູ່"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"ຫ້າມລົບກວນ ປິດຢູ່"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ (<xliff:g id="ID_1">%s</xliff:g>). ເກັບການຕັ້ງຄ່າປັດຈຸບັນໄວ້ບໍ?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍແອັບໜຶ່ງ (<xliff:g id="ID_1">%s</xliff:g>). ເກັບການຕັ້ງຄ່າປັດຈຸບັນໄວ້ບໍ?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ ຫຼື ແອັບໃດໜຶ່ງ. ເກັບການຕັ້ງຄ່າປັດຈຸບັນໄວ້ບໍ?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"ຈົນຮອດ <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"ເກັບໄວ້"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"ແທນທີ່"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4743c98..51d738c 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -166,8 +166,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Įkraunamas akumuliatorius, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> proc."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Sistemos nustatymai"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Pranešimai."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Žr. visus pranešimus"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Išvalyti pranešimą."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS įgalintas."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Gaunama GPS."</string>
@@ -751,9 +750,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"„Wi-Fi“ išjungtas"</string>
<string name="bt_is_off" msgid="2640685272289706392">"„Bluetooth“ išjungtas"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Netrukdymo režimas išjungtas"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Netrukdymo režimas įjungtas naudojant automatinę taisyklę (<xliff:g id="ID_1">%s</xliff:g>). Palikti dabartinius nustatymus?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Netrukdymo režimą įjungė programa (<xliff:g id="ID_1">%s</xliff:g>). Palikti dabartinius nustatymus?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Netrukdymo režimas įjungtas naudojant automatinę taisyklę arba programą. Palikti dabartinius nustatymus?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Iki <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Palikti"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Pakeisti"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 3e68272..b32ac24 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -165,8 +165,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Notiek akumulatora uzlāde, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenti."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Sistēmas iestatījumi"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Paziņojumi"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Skatīt visus paziņojumus"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Notīrīt paziņojumu"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ir iespējots."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS iegūšana."</string>
@@ -747,9 +746,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ir izslēgts"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth ir izslēgts"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Režīms “Netraucēt” ir izslēgts"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Režīmu “Netraucēt” ieslēdza automātiska kārtula (<xliff:g id="ID_1">%s</xliff:g>). Vai paturēt pašreizējos iestatījumus?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Režīmu “Netraucēt” ieslēdza lietotne (<xliff:g id="ID_1">%s</xliff:g>). Vai paturēt pašreizējos iestatījumus?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Režīmu “Netraucēt” ieslēdza automātiska kārtula vai lietotne. Vai paturēt pašreizējos iestatījumus?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Līdz: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Paturēt"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Aizstāt"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 49e4d53..1ecb7cf 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi е исклучено"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth е исклучен"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"„Не вознемирувај“ е исклучено"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Автоматското правило ја вклучи „Не вознемирувај“ (<xliff:g id="ID_1">%s</xliff:g>). Да се задржат тековните поставки?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Апликацијата (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“. Да се задржат тековните поставки?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Некое автоматско правило или апликација ја вклучи „Не вознемирувај“. Да се задржат тековните поставки?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"До <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Задржи"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замени"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e7c7fed..6032246 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"വൈഫൈ ഓഫാണ്"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth ഓഫാണ്"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\'ശല്യപ്പെടുത്തരുത്\' ഓഫാണ്"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"സ്വയമേവയുള്ള ഒരു നയം (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു. നിലവിലെ ക്രമീകരണം നിലനിർത്തണോ?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"ഒരു ആപ്പ് (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു. നിലവിലെ ക്രമീകരണം നിലനിർത്തണോ?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"സ്വയമേവയുള്ള ഒരു നയമോ ആപ്പോ \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു. നിലവിലെ ക്രമീകരണം നിലനിർത്തണോ?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> വരെ"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"സൂക്ഷിക്കുക"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"മാറ്റിസ്ഥാപിക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 3947464..d33849d 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -162,8 +162,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Тэжээлийг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> хувь."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Системийн тохиргоо."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Мэдэгдэл."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Бүх мэдэгдлийг харах"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Мэдэгдлийг цэвэрлэх."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS идэвхтэй."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS хайж байна."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi унтраалттай байна"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth унтраалттай байна"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Бүү саад бол горим унтраалттай байна"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Бүү саад бол горимыг автомат дүрэм (<xliff:g id="ID_1">%s</xliff:g>) асаасан. Одоогийн тохиргоог хадгалах уу?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Апп-д (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан. Одоогийн тохиргоог хадгалах уу?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Бүү саад бол горимыг автомат дүрэм эсвэл апп асаасан. Одоогийн тохиргоог хадгалах уу?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> хүртэл"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Хадгалах"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Солих"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 75b3b15..692753d2 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -743,9 +743,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"वाय-फाय बंद आहे"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ब्लूटुथ बंद आहे"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"व्यत्यय आणू नका बंद आहे"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"व्यत्यय आणू नका एक स्वयंचलित <xliff:g id="ID_1">%s</xliff:g> नियमाने चालू केले. वर्तमान सेटिंग्ज ठेवायच्या?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) अॅपने चालू केले. वर्तमान सेटिंग्ज ठेवायच्या?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"व्यत्यय आणू नका एका स्वयंचलित नियमाने किंवा अॅपने चालू केले. वर्तमान सेटिंग्ज ठेवायच्या?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> पर्यंत"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"ठेवा"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"पुनर्स्थित करा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index a911581..89070f7 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateri mengecas, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> peratus."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Tetapan sistem."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Lihat semua pemberitahuan"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Padamkan pemberitahuan."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS didayakan."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS sedang mendapatkan."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi dimatikan"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth dimatikan"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Jangan Ganggu dimatikan"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Jangan Ganggu telah dihidupkan oleh peraturan automatik (<xliff:g id="ID_1">%s</xliff:g>). Simpan tetapan semasa?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Jangan Ganggu dihidupkan oleh apl (<xliff:g id="ID_1">%s</xliff:g>). Simpan tetapan semasa?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Jangan Ganggu telah dihidupkan oleh peraturan automatik atau apl. Simpan tetapan semasa?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Hingga <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Simpan"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Gantikan"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 8108284..c7fb3d3 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ကို ပိတ်ထားသည်"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ဘလူးတုသ်ကို ပိတ်ထားသည်"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"မနှောင့်ယှက်ရ\" ကို ပိတ်ထားသည်"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"အလိုအလျောက်စည်းမျဉ်း (<xliff:g id="ID_1">%s</xliff:g>) က \"မနှောင့်ယှက်ရ\" ကို ဖွင့့့်််လိုက်ပါသည်။ လက်ရှိဆက်တင်များကို သိမ်းလိုပါသလား။"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"အက်ပ် (<xliff:g id="ID_1">%s</xliff:g>) က \"မနှောင့်ယှက်ရ\" ကို ဖွင့်လိုက်ပါသည်။ လက်ရှိဆက်တင်များကို သိမ်းလိုပါသလား။"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"အလိုအလျောက်စည်းမျဉ်း သို့မဟုတ် အက်ပ်တစ်ခုက \"မနှောင့်ယှက်ရ\" ကို ဖွင့့့်််လိုက်ပါသည်။ လက်ရှိဆက်တင်များကို သိမ်းလိုပါသလား။"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> အထိ"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"သိမ်းထားရန်"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"အစားထိုးရန်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f7f8e9d..5bf6d52 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet lades – <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prosent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Systeminnstillinger."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Varsler."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Se alle varslene"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Fjern varsling"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS er aktivert."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Henting av GPS-signal."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi er av"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth er av"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Ikke forstyrr er av"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Ikke forstyrr ble slått på av en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>). Vil du beholde de nåværende innstillingene?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Ikke forstyrr ble slått på av en app (<xliff:g id="ID_1">%s</xliff:g>). Vil du beholde de nåværende innstillingene?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Ikke forstyrr ble slått på av en automatisk regel eller en app. Vil du beholde de nåværende innstillingene?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Til <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behold"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Erstatt"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 80d4928..815293e 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ब्याट्री चार्ज हुँदैछ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> प्रतिशत।"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"प्रणाली सेटिङहरू"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाहरू।"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"सबै सूचनाहरू हेर्नुहोस्"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"सूचना खाली गर्नुहोस्।"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS सक्षम गरिएको"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS प्राप्त हुँदैछ।"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi‑Fi निष्क्रिय छ"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ब्लुटुथ निष्क्रिय छ"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"बाधा नपुर्याउनुहोस् नामक विकल्प निष्क्रिय छ"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"कुनै स्वचालित नियमले बाधा नपुर्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो(<xliff:g id="ID_1">%s</xliff:g>)। हालका सेटिङहरू राख्ने हो?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"कुनै अनुप्रयोगले बाधा नपुर्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)। हालका सेटिङहरू राख्ने हो?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"कुनै स्वचालित नियम वा अनुप्रयोगले बाधा नपुर्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो। हालका सेटिङहरू राख्ने हो?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> सम्म"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"राख्नुहोस्"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"प्रतिस्थापन गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 745dac2..1ad45bd 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wifi is uitgeschakeld"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth is uitgeschakeld"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\'Niet storen\' is uitgeschakeld"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\'Niet storen\' is ingeschakeld door een automatische regel (<xliff:g id="ID_1">%s</xliff:g>). Huidige instellingen behouden?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\'Niet storen\' is ingeschakeld door een app (<xliff:g id="ID_1">%s</xliff:g>). Huidige instellingen behouden?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\'Niet storen\' is ingeschakeld voor een automatische regel of app. Huidige instellingen behouden?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Tot <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behouden"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Vervangen"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index fc99a06..183b22c 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ਬੈਟਰੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ।"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ।"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"ਸੂਚਨਾਵਾਂ।"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖੋ"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"ਸੂਚਨਾ ਹਟਾਓ।"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ਸਮਰਥਿਤ।"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS ਪ੍ਰਾਪਤ ਕਰ ਰਿਹਾ ਹੈ।"</string>
@@ -561,7 +560,7 @@
</plurals>
<string name="notification_all_categories" msgid="5407190218055113282">"ਸਭ ਸ਼੍ਰੇਣੀਆਂ"</string>
<string name="notification_more_settings" msgid="816306283396553571">"ਹੋਰ ਸੈਟਿੰਗਾਂ"</string>
- <string name="notification_app_settings" msgid="3743278649182392015">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
+ <string name="notification_app_settings" msgid="3743278649182392015">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਰੋ: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
<string name="notification_done" msgid="5279426047273930175">"ਹੋ ਗਿਆ"</string>
<string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
<string name="notification_menu_gear_description" msgid="2204480013726775108">"ਸੂਚਨਾ ਕੰਟਰੋਲ"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ਬੰਦ ਹੈ"</string>
<string name="bt_is_off" msgid="2640685272289706392">"ਬਲੂਟੁੱਥ ਬੰਦ ਹੈ"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"ਸਵੈਚਲਿਤ ਨਿਯਮ ਦੁਆਰਾ \'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ (<xliff:g id="ID_1">%s</xliff:g>)। ਵਰਤਮਾਨ ਸੈਟਿੰਗਾਂ ਰੱਖੀਏ?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"ਐਪ ਵੱਲੋਂ \'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ (<xliff:g id="ID_1">%s</xliff:g>)। ਵਰਤਮਾਨ ਸੈਟਿੰਗਾਂ ਰੱਖੀਏ?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"ਸਵੈਚਲਿਤ ਨਿਯਮ ਜਾਂ ਐਪ ਵੱਲੋਂ \'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ। ਵਰਤਮਾਨ ਸੈਟਿੰਗਾਂ ਰੱਖੀਏ?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> ਤੱਕ"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"ਰੱਖੋ"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"ਬਦਲੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index a8a9a3f..8b9ee0b 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -166,8 +166,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Ładuję baterię, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Ustawienia systemu."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Powiadomienia."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Zobacz wszystkie powiadomienia"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Usuń powiadomienie."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS włączony."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Pobieranie danych GPS."</string>
@@ -751,9 +750,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi jest wyłączone"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth jest wyłączony"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Tryb Nie przeszkadzać jest wyłączony"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną (<xliff:g id="ID_1">%s</xliff:g>). Zachować obecne ustawienia?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Tryb Nie przeszkadzać został włączony przez aplikację (<xliff:g id="ID_1">%s</xliff:g>). Zachować obecne ustawienia?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną lub aplikację. Zachować obecne ustawienia?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Do: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zachowaj"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zastąp"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 6be8858..45e2fda 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ver todas as notificações"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificação."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ativado."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Aquisição de GPS."</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"O Wi-Fi está desativado"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth desativado"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"O recurso Não perturbe está desativado"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>). Manter as configurações atuais?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>). Manter as configurações atuais?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"O recurso Não perturbe foi ativado por uma regra automática ou app. Manter as configurações atuais?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Até <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 79f6aa9..741b3d6 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desativado"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth desativado"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Não incomodar desativado"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Não incomodar foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>). Pretende manter as definições atuais?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Não incomodar foi ativado por uma aplicação (<xliff:g id="ID_1">%s</xliff:g>). Pretende manter as definições atuais?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Não incomodar foi ativado por uma regra automática ou uma aplicação. Pretende manter as definições atuais?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Até à(s) <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 6be8858..45e2fda 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ver todas as notificações"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificação."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ativado."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Aquisição de GPS."</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"O Wi-Fi está desativado"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth desativado"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"O recurso Não perturbe está desativado"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>). Manter as configurações atuais?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>). Manter as configurações atuais?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"O recurso Não perturbe foi ativado por uma regra automática ou app. Manter as configurações atuais?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Até <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 7605103..e7dffee 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -748,9 +748,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Conexiunea Wi-Fi este dezactivată"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Funcția Bluetooth este dezactivată"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Funcția Nu deranja este dezactivată"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Funcția Nu deranja a fost activată de o regulă automată (<xliff:g id="ID_1">%s</xliff:g>). Păstrați setările actuale?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Funcția Nu deranja a fost activată de o aplicație (<xliff:g id="ID_1">%s</xliff:g>). Păstrați setările actuale?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Funcția Nu deranja a fost activată de o regulă automată sau de o aplicație. Păstrați setările actuale?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Până la <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Păstrați"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Înlocuiți"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index cd8053d..75310a3 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -168,8 +168,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Настройки"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Уведомления"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Показать все уведомления"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Удалить уведомление"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"Система GPS включена."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Установление связи с GPS."</string>
@@ -753,9 +752,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Модуль Wi-Fi отключен"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Модуль Bluetooth отключен"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Режим \"Не беспокоить\" отключен"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Режим \"Не беспокоить\" был включен специальным правилом (<xliff:g id="ID_1">%s</xliff:g>). Сохранить текущие настройки?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Режим \"Не беспокоить\" был включен приложением (<xliff:g id="ID_1">%s</xliff:g>). Сохранить текущие настройки?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Режим \"Не беспокоить\" был включен специальным правилом или приложением. Сохранить текущие настройки?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"До <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Сохранить"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Заменить"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 52f49bf..c71d5a2 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"බැටරිය ආරෝපණය කරමින්, සියයට <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"පද්ධති සැකසීම්."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"දැනුම්දීම්."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"සියලු දැනුම්දීම් බලන්න"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"දැනුම්දීම හිස් කරන්න."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS සබල කර ඇත."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS ලබා ගනිමින්."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ක්රියා විරහිතයි"</string>
<string name="bt_is_off" msgid="2640685272289706392">"බ්ලූටූත් ක්රියා විරහිතයි"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"බාධා නොකරන්න ක්රියා විරහිතයි"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"බාධා නොකරන්න ස්වයංක්රීය රීතියකින් ක්රියාත්මක කෙරිණි (<xliff:g id="ID_1">%s</xliff:g>). වත්මන් සැකසීම් තබා ගන්නවා ද?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"බාධා නොකරන්න යෙදුමකින් ක්රියාත්මක කෙරිණි (<xliff:g id="ID_1">%s</xliff:g>). වත්මන් සැකසීම් තබා ගන්නවා ද?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"බාධා නොකරන්න ස්වයංක්රීය රීතියකින් හෝ යෙදුමකින් ක්රියාත්මක කෙරිණි. වත්මන් සැකසීම් තබා ගන්නවා ද?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> දක්වා"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"තබන්න"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"ප්රතිස්ථාපනය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index de8ad54..59dce6f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -168,8 +168,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Nastavenia systému."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Upozornenia."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Zobraziť všetky upozornenia"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Vymazať upozornenie."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS je povolené."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Prebieha zameriavanie GPS."</string>
@@ -753,9 +752,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Pripojenie Wi-Fi je vypnuté"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Rozhranie Bluetooth je vypnuté"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Nastavenie Nerušiť je vypnuté"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Nastavenie Nerušiť bolo zapnuté automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>). Chcete ponechať aktuálne nastavenia?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Nastavenie Nerušiť bolo zapnuté aplikáciou (<xliff:g id="ID_1">%s</xliff:g>). Chcete ponechať aktuálne nastavenia?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Nastavenie Nerušiť bolo zapnuté automatickým pravidlom alebo aplikáciou. Chcete ponechať aktuálne nastavenia?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Ponechať"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradiť"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 55699fa..53ae44e 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -168,8 +168,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Sistemske nastavitve."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Obvestila."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Prikaži vsa obvestila"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Izbriši obvestilo."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS omogočen."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Pridobivanje GPS."</string>
@@ -753,9 +752,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je izklopljen"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je izklopljen"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Način »ne moti« je izklopljen"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Samodejno pravilo (<xliff:g id="ID_1">%s</xliff:g>) je vklopilo način »ne moti«. Želite obdržati trenutne nastavitve?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je vklopila način »ne moti«. Želite obdržati trenutne nastavitve?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Način »ne moti« je vklopljen zaradi samodejnega pravila ali aplikacije. Želite obdržati trenutne nastavitve?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Obdrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamenjaj"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index c47fc40..12573bc 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria po ngarkohet, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> për qind."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Cilësimet e sistemit."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Njoftimet."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Shiko të gjitha njoftimet"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Pastro njoftimin."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS-ja është e aktivizuar."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Po siguron GPS-në."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi është joaktiv"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth-i është joaktiv"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Modaliteti \"Mos shqetëso\" është joaktiv"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik (<xliff:g id="ID_1">%s</xliff:g>). Të mbahen cilësimet aktuale?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një aplikacion (<xliff:g id="ID_1">%s</xliff:g>). Të mbahen cilësimet aktuale?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik ose një aplikacion. Të mbahen cilësimet aktuale?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Deri në <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Mbaj"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zëvendëso"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index c47ac3f..664c308 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -746,9 +746,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi је искључен"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth је искључен"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Режим Не узнемиравај је искључен"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај. Желите ли да задржите актуелна подешавања?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Апликација (<xliff:g id="ID_1">%s</xliff:g>) је укључила режим Не узнемиравај. Желите ли да задржите актуелна подешавања?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Аутоматско правило или апликација су укључили режим Не узнемиравај. Желите ли да задржите актуелна подешавања?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"До <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Задржи"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замени"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 682de56..65d0712 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi är inaktiverat"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth är inaktiverat"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Stör ej är inaktiverat"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Stör ej aktiverades av en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>). Vill du behålla de nuvarande inställningarna?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Stör ej aktiverades av en app (<xliff:g id="ID_1">%s</xliff:g>). Vill du behålla de nuvarande inställningarna?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Stör ej aktiverades av en automatisk regel eller app. Vill du behålla de nuvarande inställningarna?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Till <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behåll"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ersätt"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 5a69fb3..1935944 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Betri inachaji, asilimia <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Mipangilio ya mfumo."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Arifa."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Angalia arifa zote"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Futa arifa"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS imewashwa."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Kupata GPS."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi imezimwa"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth imezimwa"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Kipengele cha Usinisumbue kimezimwa"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki (<xliff:g id="ID_1">%s</xliff:g>). Ungependa kutumia mipangilio ya sasa?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Kipengele cha Usinisumbue kimewashwa na programu (<xliff:g id="ID_1">%s</xliff:g>). Ungependa kutumia mipangilio ya sasa?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki au programu. Ungependa kutumia mipangilio ya sasa?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Hadi <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Usibadilishe"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Badilisha"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 495f5c3..36d247f 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"வைஃபை முடக்கத்தில் உள்ளது"</string>
<string name="bt_is_off" msgid="2640685272289706392">"புளூடூத் முடக்கத்தில் உள்ளது"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"தொந்தரவு செய்ய வேண்டாம்\" முடக்கத்தில் உள்ளது"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது. தற்போதைய அமைப்புகளையே வைத்திருக்கவா?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, பயன்பாடு (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது. தற்போதைய அமைப்புகளையே வைத்திருக்கவா?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி அல்லது பயன்பாடு இயக்கியுள்ளது. தற்போதைய அமைப்புகளையே வைத்திருக்கவா?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> வரை"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"வைத்திரு"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"மாற்று"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 07447cf..766ee06 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"బ్యాటరీ ఛార్జ్ అవుతోంది, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> శాతం."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"సిస్టమ్ సెట్టింగ్లు."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"నోటిఫికేషన్లు."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"అన్ని నోటిఫికేషన్లను చూడండి"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"నోటిఫికేషన్ను క్లియర్ చేయండి."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ప్రారంభించబడింది."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPSని పొందడం."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ఆఫ్లో ఉంది"</string>
<string name="bt_is_off" msgid="2640685272289706392">"బ్లూటూత్ ఆఫ్లో ఉంది"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"అంతరాయం కలిగించవద్దు ఆఫ్లో ఉంది"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"స్వయంచాలక నియమం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది. ప్రస్తుత సెట్టింగ్లను కొనసాగించాలా?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"అనువర్తనం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది. ప్రస్తుత సెట్టింగ్లను కొనసాగించాలా?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"స్వయంచాలక నియమం లేదా అనువర్తనం ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది. ప్రస్తుత సెట్టింగ్లను కొనసాగించాలా?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> వరకు"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"ఉంచు"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"భర్తీ చేయి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 09a734e..ef281dc 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"กำลังชาร์จแบตเตอรี่ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> เปอร์เซ็นต์"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"การตั้งค่าระบบ"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"การแจ้งเตือน"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"ดูการแจ้งเตือนทั้งหมด"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"ล้างการแจ้งเตือน"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"เปิดใช้งาน GPS แล้ว"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"การดึงข้อมูล GPS"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ปิดอยู่"</string>
<string name="bt_is_off" msgid="2640685272289706392">"บลูทูธปิดอยู่"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\"ห้ามรบกวน\" ปิดอยู่"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติ (<xliff:g id="ID_1">%s</xliff:g>) ให้คงการตั้งค่าปัจจุบันใช่ไหม"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"มีการเปิด \"ห้ามรบกวน\" โดยแอป (<xliff:g id="ID_1">%s</xliff:g>) ให้คงการตั้งค่าปัจจุบันใช่ไหม"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติหรือแอป ให้คงการตั้งค่าปัจจุบันใช่ไหม"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"จนถึง <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"เก็บไว้"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"แทนที่"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index c902863..9a0bad7 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Nagcha-charge ang baterya, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> (na) porsyento."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Mga setting ng system."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Mga Notification."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Tingnan ang lahat ng notification"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"I-clear ang notification."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"Pinapagana ang GPS."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Kumukuha ng GPS."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Naka-off ang Wi-Fi"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Naka-off ang Bluetooth"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Naka-off ang Huwag Istorbohin"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan (<xliff:g id="ID_1">%s</xliff:g>). Panatilihin ang mga kasalukuyang setting?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Na-on ang Huwag Istorbohin dahil sa isang app (<xliff:g id="ID_1">%s</xliff:g>). Panatilihin ang mga kasalukuyang setting?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan o app. Panatilihin ang mga kasalukuyang setting?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Hanggang <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Panatilihin"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Palitan"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index de8f193..af703c0 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Pil şarj oluyor, yüzde <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Sistem ayarları."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirimler."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Tüm bildirimleri göster"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Bildirimi temizle."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS etkin."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS alınıyor."</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Kablosuz bağlantı kapalı"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth kapalı"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Rahatsız Etmeyin kapalı"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Rahatsız Etmeyin ayarı bir otomatik kural (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı. Geçerli ayarlar korunsun mu?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Rahatsız Etmeyin ayarı bir uygulama (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı. Geçerli ayarlar korunsun mu?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Rahatsız Etmeyin ayarı bir otomatik kural veya uygulama tarafından açıldı. Geçerli ayarlar korunsun mu?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Bitiş: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Koru"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Değiştir"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2f86651..8edfa59 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -752,9 +752,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi вимкнено"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth вимкнено"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Режим \"Не турбувати\" вимкнено"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Автоматичне правило ввімкнуло режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>). Залишити поточні налаштування?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Додаток увімкнув режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>). Залишити поточні налаштування?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Автоматичне правило або додаток увімкнули режим \"Не турбувати\". Залишити поточні налаштування?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"До <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Залишити"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замінити"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 37b38cc..572f327 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"بیٹری چارجنگ، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> فیصد۔"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"سسٹم کی ترتیبات۔"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"اطلاعات۔"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"تمام اطلاعات دیکھیں"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"اطلاع صاف کریں۔"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS فعال ہے۔"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS حاصل کرنا۔"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi آف ہے"</string>
<string name="bt_is_off" msgid="2640685272289706392">"بلوٹوتھ آف ہے"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"\'ڈسٹرب نہ کریں\' آف ہے"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعے آن ہو گیا تھا۔ موجودہ ترتیبات برقرار رکھیں؟"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"\'ڈسٹرب نہ کریں\' کسی ایپ (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعے آن ہو گیا تھا۔ موجودہ ترتیبات برقرار رکھیں؟"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول یا ایپ کے ذریعے آن ہو گیا تھا۔ موجودہ ترتیبات برقرار رکھیں؟"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> تک"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"رکھیں"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"بدلیں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index bc6fa7a..2f0fa7f 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -744,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi o‘chiq"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth o‘chiq"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Bezovta qilinmasin rejimi o‘chiq"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Bezovta qilinmasin rejimi avtomatik qoida (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan. Joriy sozlamalar saqlab qolinsimi?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Bezovta qilinmasin rejimi ilova (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan. Joriy sozlamalar saqlab qolinsimi?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Bezovta qilinmasin rejimi ilova yoki avtomatik qoida tomonidan yoqilgan. Joriy sozlamalar saqlab qolinsimi?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> gacha"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Saqlab qolish"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Almashtirish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 942545f..e9bc587 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Đang sạc pin, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> phần trăm."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Cài đặt hệ thống"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Thông báo."</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"Xem tất cả thông báo"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Xóa thông báo"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"Đã bật GPS."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Nhận GPS."</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi tắt"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth tắt"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Không làm phiền tắt"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Không làm phiền đã được một quy tắc tự động (<xliff:g id="ID_1">%s</xliff:g>) bật. Giữ cài đặt hiện tại?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Không làm phiền đã được một ứng dụng (<xliff:g id="ID_1">%s</xliff:g>) bật. Giữ cài đặt hiện tại?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Không làm phiền đã được một quy tắc tự động hoặc ứng dụng bật. Giữ cài đặt hiện tại?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Cho tới <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Giữ"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Thay thế"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 35958ff..a855481 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"正在充电,已完成百分之<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>。"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"系统设置。"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"查看所有通知"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS已启用。"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"正在获取GPS信号。"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"WLAN 已关闭"</string>
<string name="bt_is_off" msgid="2640685272289706392">"蓝牙已关闭"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"“勿扰”模式已关闭"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"有个自动规则(<xliff:g id="ID_1">%s</xliff:g>)已开启“勿扰”模式。要保留当前的设置吗?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"有个应用(<xliff:g id="ID_1">%s</xliff:g>)已开启“勿扰”模式。要保留当前的设置吗?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"有个自动规则或应用已开启“勿扰”模式。要保留当前的设置吗?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"直到<xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"保留"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"替换"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 5a7d676..52d7650 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -166,8 +166,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"睇所有通知"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS 已啟用。"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"正在取得 GPS 訊號。"</string>
@@ -745,9 +744,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi 已關閉"</string>
<string name="bt_is_off" msgid="2640685272289706392">"藍牙已關閉"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"「請勿騷擾」已關閉"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已開啟「請勿騷擾」。要保留目前的設定嗎?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已開啟「請勿騷擾」。要保留目前的設定嗎?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"某個自動規則或應用程式已開啟「請勿騷擾」。要保留目前的設定嗎?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"直至<xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"保留"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"取代"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 15b4c2c..cd3eb55 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -164,8 +164,7 @@
<string name="accessibility_battery_level_charging" msgid="1147587904439319646">"充電中,已完成百分之 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>。"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
- <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
- <skip />
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"查看所有通知"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS 已啟用。"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"正在取得 GPS 訊號。"</string>
@@ -743,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi 已關閉"</string>
<string name="bt_is_off" msgid="2640685272289706392">"藍牙已關閉"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"零打擾模式已關閉"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已將零打擾模式開啟。要保留目前的設定嗎?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已將零打擾模式開啟。要保留目前的設定嗎?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"某個自動規則或應用程式已將零打擾模式開啟。要保留目前的設定嗎?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"直到 <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"保留"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"取代"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index ce52e7e..4914477 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -742,9 +742,12 @@
<string name="wifi_is_off" msgid="1838559392210456893">"I-Wi-Fi ivaliwe"</string>
<string name="bt_is_off" msgid="2640685272289706392">"I-Bluetooth ivaliwe"</string>
<string name="dnd_is_off" msgid="6167780215212497572">"Ungaphazamisi kuvaliwe"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="1570808639425342">"Ungaphazamisi kuvulwe umthetho wokuzenzakalelayo (<xliff:g id="ID_1">%s</xliff:g>). Gcina izilungiselelo zamanje?"</string>
- <string name="qs_dnd_prompt_app" msgid="1131614608680529190">"Ungaphazamisi kuvulwe uhlelo lokusebenza (<xliff:g id="ID_1">%s</xliff:g>). Gcina izilungiselelo zamanje?"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="3685659782196144067">"Ungaphazamisi kuvulwe umthetho ozenzakalelayo noma uhlelo lokusebenza. Gcina izilungiselelo zamanje?"</string>
+ <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+ <skip />
+ <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+ <skip />
<string name="qs_dnd_until" msgid="3469471136280079874">"Kuze kube-<xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Gcina"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Buyisela"</string>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d68487c..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] -->
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 429e859..f4d4a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -42,6 +42,7 @@
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
import com.android.systemui.statusbar.policy.AccessibilityController;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryControllerImpl;
import com.android.systemui.statusbar.policy.BluetoothController;
@@ -260,6 +261,9 @@
mProviders.put(MetricsLogger.class, () -> new MetricsLogger());
+ mProviders.put(AccessibilityManagerWrapper.class,
+ () -> new AccessibilityManagerWrapper(mContext));
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 9b3ee30..1151c8c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -35,8 +35,8 @@
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSIconView;
import com.android.systemui.plugins.qs.QSTile.SignalState;
-import com.android.systemui.qs.CellTileView;
import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.SignalTileView;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
@@ -83,7 +83,7 @@
@Override
public QSIconView createTileView(Context context) {
- return new CellTileView(context);
+ return new SignalTileView(context);
}
@Override
@@ -118,15 +118,6 @@
}
final Resources r = mContext.getResources();
- final int iconId = cb.noSim ? R.drawable.ic_qs_no_sim
- : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled
- : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId
- : R.drawable.ic_qs_signal_no_signal;
- if (cb.dataTypeIconId != 0) {
- state.icon = ResourceIcon.get(cb.dataTypeIconId);
- } else {
- state.icon = ResourceIcon.get(iconId);
- }
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
@@ -136,8 +127,16 @@
state.expandedAccessibilityClassName = Switch.class.getName();
state.value = mDataController.isMobileDataSupported()
&& mDataController.isMobileDataEnabled();
- state.state = cb.airplaneModeEnabled ? Tile.STATE_UNAVAILABLE
+ state.icon = ResourceIcon.get(R.drawable.ic_data_unavailable);
+ state.state = cb.airplaneModeEnabled || !cb.enabled ? Tile.STATE_UNAVAILABLE
: state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+ if (state.state == Tile.STATE_ACTIVE) {
+ state.icon = ResourceIcon.get(R.drawable.ic_data_on);
+ } else if (state.state == Tile.STATE_INACTIVE) {
+ state.icon = ResourceIcon.get(R.drawable.ic_data_off);
+ } else {
+ state.icon = ResourceIcon.get(R.drawable.ic_data_unavailable);
+ }
}
@Override
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 7562399..fa404b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -64,6 +64,7 @@
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -78,6 +79,7 @@
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.KeyButtonView;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -138,8 +140,8 @@
mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
mWindowManager = getContext().getSystemService(WindowManager.class);
mAccessibilityManager = getContext().getSystemService(AccessibilityManager.class);
- mAccessibilityManager.addAccessibilityServicesStateChangeListener(
- this::updateAccessibilityServicesState);
+ Dependency.get(AccessibilityManagerWrapper.class).addCallback(
+ mAccessibilityListener);
mContentResolver = getContext().getContentResolver();
mMagnificationObserver = new MagnificationContentObserver(
getContext().getMainThreadHandler());
@@ -164,8 +166,8 @@
public void onDestroy() {
super.onDestroy();
mCommandQueue.removeCallbacks(this);
- mAccessibilityManager.removeAccessibilityServicesStateChangeListener(
- this::updateAccessibilityServicesState);
+ Dependency.get(AccessibilityManagerWrapper.class).removeCallback(
+ mAccessibilityListener);
mContentResolver.unregisterContentObserver(mMagnificationObserver);
try {
WindowManagerGlobal.getWindowManagerService()
@@ -625,6 +627,9 @@
mNavigationBarView.getBarTransitions().finishAnimations();
}
+ private final AccessibilityServicesStateChangeListener mAccessibilityListener =
+ this::updateAccessibilityServicesState;
+
private class MagnificationContentObserver extends ContentObserver {
public MagnificationContentObserver(Handler handler) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
new file mode 100644
index 0000000..dfa5cbd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
+
+/**
+ * For mocking because AccessibilyManager is final for some reason...
+ */
+public class AccessibilityManagerWrapper implements
+ CallbackController<AccessibilityServicesStateChangeListener> {
+
+ private final AccessibilityManager mAccessibilityManager;
+
+ public AccessibilityManagerWrapper(Context context) {
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+ }
+
+ @Override
+ public void addCallback(AccessibilityServicesStateChangeListener listener) {
+ mAccessibilityManager.addAccessibilityServicesStateChangeListener(listener);
+ }
+
+ @Override
+ public void removeCallback(AccessibilityServicesStateChangeListener listener) {
+ mAccessibilityManager.removeAccessibilityServicesStateChangeListener(listener);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index e7cdcb5..53d842a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -14,12 +14,14 @@
package com.android.systemui.statusbar.phone;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import android.testing.AndroidTestingRunner;
+import android.testing.LeakCheck.Tracker;
import android.view.Display;
import android.view.WindowManager;
@@ -29,11 +31,18 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.utils.leaks.BaseLeakChecker;
+
import android.testing.TestableLooper.RunWithLooper;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
@@ -56,6 +65,20 @@
when(windowManager.getDefaultDisplay()).thenReturn(
defaultDisplay);
mContext.addMockSystemService(Context.WINDOW_SERVICE, windowManager);
+
+ Tracker tracker = mLeakCheck.getTracker("accessibility_manager");
+ AccessibilityManagerWrapper wrapper = new AccessibilityManagerWrapper(mContext) {
+ @Override
+ public void addCallback(AccessibilityServicesStateChangeListener listener) {
+ tracker.getLeakInfo(listener).addAllocation(new Throwable());
+ }
+
+ @Override
+ public void removeCallback(AccessibilityServicesStateChangeListener listener) {
+ tracker.getLeakInfo(listener).clearAllocations();
+ }
+ };
+ mDependency.injectTestDependency(AccessibilityManagerWrapper.class, wrapper);
}
@Test
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 579c54c..f56cbdd 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3906,6 +3906,11 @@
// OS: O
FINGERPRINT_REMOVE_SIDECAR = 934;
+ // OPEN: Settings > Storage > Movies & TV
+ // CATEGORY: SETTINGS
+ // OS: O
+ APPLICATIONS_STORAGE_MOVIES = 935;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
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 0488d22..0003941 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -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/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 9218c25..d25b3cc 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -84,6 +84,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
+import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
@@ -106,6 +107,7 @@
private final Object mServiceConnectionLock = new Object();
private final Handler mHandler;
private final DispatchingContentObserver mContentObserver;
+ private final Function<NetworkScorerAppData, ScoringServiceConnection> mServiceConnProducer;
@GuardedBy("mPackageMonitorLock")
private NetworkScorerPackageMonitor mPackageMonitor;
@@ -238,11 +240,13 @@
}
public NetworkScoreService(Context context) {
- this(context, new NetworkScorerAppManager(context), Looper.myLooper());
+ this(context, new NetworkScorerAppManager(context),
+ ScoringServiceConnection::new, Looper.myLooper());
}
@VisibleForTesting
NetworkScoreService(Context context, NetworkScorerAppManager networkScoreAppManager,
+ Function<NetworkScorerAppData, ScoringServiceConnection> serviceConnProducer,
Looper looper) {
mContext = context;
mNetworkScorerAppManager = networkScoreAppManager;
@@ -257,6 +261,7 @@
mRecommendationRequestTimeoutMs = TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS;
mHandler = new ServiceHandler(looper);
mContentObserver = new DispatchingContentObserver(context, mHandler);
+ mServiceConnProducer = serviceConnProducer;
}
/** Called when the system is ready to run third-party code but before it actually does so. */
@@ -356,17 +361,17 @@
synchronized (mServiceConnectionLock) {
// If we're connected to a different component then drop it.
if (mServiceConnection != null
- && !mServiceConnection.mAppData.equals(appData)) {
+ && !mServiceConnection.getAppData().equals(appData)) {
unbindFromScoringServiceIfNeeded();
}
// If we're not connected at all then create a new connection.
if (mServiceConnection == null) {
- mServiceConnection = new ScoringServiceConnection(appData);
+ mServiceConnection = mServiceConnProducer.apply(appData);
}
// Make sure the connection is connected (idempotent)
- mServiceConnection.connect(mContext);
+ mServiceConnection.bind(mContext);
}
} else { // otherwise make sure it isn't bound.
unbindFromScoringServiceIfNeeded();
@@ -377,9 +382,9 @@
if (DBG) Log.d(TAG, "unbindFromScoringServiceIfNeeded");
synchronized (mServiceConnectionLock) {
if (mServiceConnection != null) {
- mServiceConnection.disconnect(mContext);
+ mServiceConnection.unbind(mContext);
if (DBG) Log.d(TAG, "Disconnected from: "
- + mServiceConnection.mAppData.getRecommendationServiceComponent());
+ + mServiceConnection.getAppData().getRecommendationServiceComponent());
}
mServiceConnection = null;
}
@@ -687,7 +692,7 @@
public boolean isCallerActiveScorer(int callingUid) {
synchronized (mServiceConnectionLock) {
return mServiceConnection != null
- && mServiceConnection.mAppData.packageUid == callingUid;
+ && mServiceConnection.getAppData().packageUid == callingUid;
}
}
@@ -720,7 +725,7 @@
if (isCallerSystemProcess(getCallingUid()) || callerCanRequestScores()) {
synchronized (mServiceConnectionLock) {
if (mServiceConnection != null) {
- return mServiceConnection.mAppData;
+ return mServiceConnection.getAppData();
}
}
} else {
@@ -1020,7 +1025,9 @@
mReqRecommendationCallerRef.set(new RequestRecommendationCaller(timeoutMs));
}
- private static class ScoringServiceConnection implements ServiceConnection {
+ // The class and methods need to be public for Mockito to work.
+ @VisibleForTesting
+ public static class ScoringServiceConnection implements ServiceConnection {
private final NetworkScorerAppData mAppData;
private volatile boolean mBound = false;
private volatile boolean mConnected = false;
@@ -1030,7 +1037,8 @@
mAppData = appData;
}
- void connect(Context context) {
+ @VisibleForTesting
+ public void bind(Context context) {
if (!mBound) {
Intent service = new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS);
service.setComponent(mAppData.getRecommendationServiceComponent());
@@ -1039,13 +1047,15 @@
UserHandle.SYSTEM);
if (!mBound) {
Log.w(TAG, "Bind call failed for " + service);
+ context.unbindService(this);
} else {
if (DBG) Log.d(TAG, "ScoringServiceConnection bound.");
}
}
}
- void disconnect(Context context) {
+ @VisibleForTesting
+ public void unbind(Context context) {
try {
if (mBound) {
mBound = false;
@@ -1056,17 +1066,30 @@
Log.e(TAG, "Unbind failed.", e);
}
+ mConnected = false;
mRecommendationProvider = null;
}
- INetworkRecommendationProvider getRecommendationProvider() {
+ @VisibleForTesting
+ public NetworkScorerAppData getAppData() {
+ return mAppData;
+ }
+
+ @VisibleForTesting
+ public INetworkRecommendationProvider getRecommendationProvider() {
return mRecommendationProvider;
}
- String getPackageName() {
+ @VisibleForTesting
+ public String getPackageName() {
return mAppData.getRecommendationServiceComponent().getPackageName();
}
+ @VisibleForTesting
+ public boolean isAlive() {
+ return mBound && mConnected;
+ }
+
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DBG) Log.d(TAG, "ScoringServiceConnection: " + name.flattenToString());
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 e6f9e53..fd7dea1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3890,7 +3890,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);
@@ -5255,10 +5256,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;
}
@@ -5273,7 +5274,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) {
@@ -7844,7 +7865,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;
}
@@ -17937,10 +17958,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;
}
}
@@ -17952,9 +17977,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;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index cfbd2b5..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,
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 0e033d2..5d474eb 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;
@@ -645,9 +644,13 @@
}
final ActivityRecord topRunningActivityLocked() {
+ return topRunningActivityLocked(false /* focusableOnly */);
+ }
+
+ final ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
- if (r != null) {
+ if (r != null && (!focusableOnly || r.isFocusable())) {
return r;
}
}
@@ -1167,8 +1170,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);
@@ -1324,7 +1325,7 @@
+ (timeout ? " (due to timeout)" : " (pause complete)"));
mService.mWindowManager.deferSurfaceLayout();
try {
- completePauseLocked(true, null);
+ completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
@@ -1803,15 +1804,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 +1993,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 +2015,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 +2023,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 */);
}
@@ -2198,8 +2202,10 @@
return false;
}
- // Find the topmost activity in this stack that is not finishing.
- final ActivityRecord next = topRunningActivityLocked();
+ // Find the next top-most activity to resume in this stack that is not finishing and is
+ // focusable. If it is not focusable, we will fall into the case below to resume the
+ // top activity in the next focusable task.
+ final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
final boolean hasRunningActivity = next != null;
@@ -3973,6 +3979,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);
@@ -5032,14 +5051,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/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index d591858..3e53aca 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -259,6 +259,12 @@
// This variable is set before transitioning to the mCaptivePortalState.
private CaptivePortalProbeResult mLastPortalProbeResult = CaptivePortalProbeResult.FAILED;
+ // Configuration values for captive portal detection probes.
+ private final String mCaptivePortalUserAgent;
+ private final URL mCaptivePortalHttpsUrl;
+ private final URL mCaptivePortalHttpUrl;
+ private final URL mCaptivePortalFallbackUrl;
+
public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
NetworkRequest defaultRequest) {
this(context, handler, networkAgentInfo, defaultRequest, new IpConnectivityLog());
@@ -293,6 +299,11 @@
mUseHttps = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
+ mCaptivePortalUserAgent = getCaptivePortalUserAgent(context);
+ mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl(context));
+ mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl(context));
+ mCaptivePortalFallbackUrl = makeURL(getCaptivePortalFallbackUrl(context));
+
start();
}
@@ -301,6 +312,11 @@
if (DBG) Log.d(TAG + "/" + mNetworkAgentInfo.name(), s);
}
+ private void validationLog(int probeType, Object url, String msg) {
+ String probeName = ValidationProbeEvent.getProbeName(probeType);
+ validationLog(String.format("%s %s %s", probeName, url, msg));
+ }
+
private void validationLog(String s) {
if (DBG) log(s);
validationLogs.log(s);
@@ -671,7 +687,10 @@
return new CaptivePortalProbeResult(204);
}
- URL pacUrl = null, httpsUrl = null, httpUrl = null, fallbackUrl = null;
+ URL pacUrl = null;
+ URL httpsUrl = mCaptivePortalHttpsUrl;
+ URL httpUrl = mCaptivePortalHttpUrl;
+ URL fallbackUrl = mCaptivePortalFallbackUrl;
// On networks with a PAC instead of fetching a URL that should result in a 204
// response, we instead simply fetch the PAC script. This is done for a few reasons:
@@ -698,13 +717,8 @@
}
}
- if (pacUrl == null) {
- httpsUrl = makeURL(getCaptivePortalServerHttpsUrl(mContext));
- httpUrl = makeURL(getCaptivePortalServerHttpUrl(mContext));
- fallbackUrl = makeURL(getCaptivePortalFallbackUrl(mContext));
- if (httpUrl == null || httpsUrl == null) {
- return CaptivePortalProbeResult.FAILED;
- }
+ if ((pacUrl == null) && (httpUrl == null || httpsUrl == null)) {
+ return CaptivePortalProbeResult.FAILED;
}
long startTime = SystemClock.elapsedRealtime();
@@ -752,20 +766,19 @@
String connectInfo;
try {
InetAddress[] addresses = mNetworkAgentInfo.network.getAllByName(host);
- result = ValidationProbeEvent.DNS_SUCCESS;
- StringBuffer buffer = new StringBuffer(host).append("=");
+ StringBuffer buffer = new StringBuffer();
for (InetAddress address : addresses) {
- buffer.append(address.getHostAddress());
- if (address != addresses[addresses.length-1]) buffer.append(",");
+ buffer.append(',').append(address.getHostAddress());
}
- connectInfo = buffer.toString();
+ result = ValidationProbeEvent.DNS_SUCCESS;
+ connectInfo = "OK " + buffer.substring(1);
} catch (UnknownHostException e) {
result = ValidationProbeEvent.DNS_FAILURE;
- connectInfo = host;
+ connectInfo = "FAIL";
}
final long latency = watch.stop();
- String resultString = (ValidationProbeEvent.DNS_SUCCESS == result) ? "OK" : "FAIL";
- validationLog(String.format("%s %s %dms, %s", name, resultString, latency, connectInfo));
+ validationLog(ValidationProbeEvent.PROBE_DNS, host,
+ String.format("%dms %s", latency, connectInfo));
logValidationProbe(latency, ValidationProbeEvent.PROBE_DNS, result);
}
@@ -786,9 +799,8 @@
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
urlConnection.setUseCaches(false);
- final String userAgent = getCaptivePortalUserAgent(mContext);
- if (userAgent != null) {
- urlConnection.setRequestProperty("User-Agent", userAgent);
+ if (mCaptivePortalUserAgent != null) {
+ urlConnection.setRequestProperty("User-Agent", mCaptivePortalUserAgent);
}
// cannot read request header after connection
String requestHeader = urlConnection.getRequestProperties().toString();
@@ -802,8 +814,7 @@
// Time how long it takes to get a response to our request
long responseTimestamp = SystemClock.elapsedRealtime();
- validationLog(ValidationProbeEvent.getProbeName(probeType) + " " + url +
- " time=" + (responseTimestamp - requestTimestamp) + "ms" +
+ validationLog(probeType, url, "time=" + (responseTimestamp - requestTimestamp) + "ms" +
" ret=" + httpResponseCode +
" request=" + requestHeader +
" headers=" + urlConnection.getHeaderFields());
@@ -815,27 +826,29 @@
// proxy server.
if (httpResponseCode == 200) {
if (probeType == ValidationProbeEvent.PROBE_PAC) {
- validationLog("PAC fetch 200 response interpreted as 204 response.");
+ validationLog(
+ probeType, url, "PAC fetch 200 response interpreted as 204 response.");
httpResponseCode = 204;
} else if (urlConnection.getContentLengthLong() == 0) {
// Consider 200 response with "Content-length=0" to not be a captive portal.
// There's no point in considering this a captive portal as the user cannot
// sign-in to an empty page. Probably the result of a broken transparent proxy.
// See http://b/9972012.
- validationLog(
+ validationLog(probeType, url,
"200 response with Content-length=0 interpreted as 204 response.");
httpResponseCode = 204;
} else if (urlConnection.getContentLengthLong() == -1) {
// When no Content-length (default value == -1), attempt to read a byte from the
// response. Do not use available() as it is unreliable. See http://b/33498325.
if (urlConnection.getInputStream().read() == -1) {
- validationLog("Empty 200 response interpreted as 204 response.");
+ validationLog(
+ probeType, url, "Empty 200 response interpreted as 204 response.");
httpResponseCode = 204;
}
}
}
} catch (IOException e) {
- validationLog("Probably not a portal: exception " + e);
+ validationLog(probeType, url, "Probably not a portal: exception " + e);
if (httpResponseCode == 599) {
// TODO: Ping gateway and DNS server and log results.
}
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/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index d6c89a4..63647ff 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -21,15 +21,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.telecom.TelecomManager;
-import android.text.TextUtils;
-import android.util.ArrayMap;
import com.android.internal.util.NotificationMessagingUtil;
@@ -56,8 +48,8 @@
@Override
public int compare(NotificationRecord left, NotificationRecord right) {
// first all colorized notifications
- boolean leftImportantColorized = isImportantColorized(left);
- boolean rightImportantColorized = isImportantColorized(right);
+ boolean leftImportantColorized = isImportantOngoingColorized(left);
+ boolean rightImportantColorized = isImportantOngoingColorized(right);
if (leftImportantColorized != rightImportantColorized) {
return -1 * Boolean.compare(leftImportantColorized, rightImportantColorized);
@@ -118,7 +110,10 @@
return -1 * Long.compare(left.getRankingTimeMs(), right.getRankingTimeMs());
}
- private boolean isImportantColorized(NotificationRecord record) {
+ private boolean isImportantOngoingColorized(NotificationRecord record) {
+ if (!isOngoing(record)) {
+ return false;
+ }
if (record.getImportance() < NotificationManager.IMPORTANCE_LOW) {
return false;
}
@@ -133,7 +128,6 @@
if (record.getImportance() < NotificationManager.IMPORTANCE_LOW) {
return false;
}
- // TODO: add whitelist
return isCall(record) || isMediaNotification(record);
}
@@ -153,8 +147,7 @@
}
private boolean isOngoing(NotificationRecord record) {
- final int ongoingFlags =
- Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_ONGOING_EVENT;
+ final int ongoingFlags = Notification.FLAG_FOREGROUND_SERVICE;
return (record.getNotification().flags & ongoingFlags) != 0;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2c7a61b..f9dff3e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3071,32 +3071,34 @@
public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId,
int userId) {
checkCallerIsSystem();
- synchronized (mNotificationLock) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- NotificationRecord r =
- findNotificationLocked(pkg, null, notificationId, userId);
- if (r == null) {
- Log.d(TAG,
- "stripForegroundServiceFlag: Could not find notification with "
- + "pkg=" + pkg + " / id=" + notificationId
- + " / userId=" + userId);
- return;
- }
- StatusBarNotification sbn = r.sbn;
- // NoMan adds flags FLAG_NO_CLEAR and FLAG_ONGOING_EVENT when it sees
- // FLAG_FOREGROUND_SERVICE. Hence it's not enough to remove
- // FLAG_FOREGROUND_SERVICE, we have to revert to the flags we received
- // initially *and* force remove FLAG_FOREGROUND_SERVICE.
- sbn.getNotification().flags =
- (r.mOriginalFlags & ~Notification.FLAG_FOREGROUND_SERVICE);
- mRankingHelper.sort(mNotificationList);
- mListeners.notifyPostedLocked(sbn, sbn /* oldSbn */);
- mGroupHelper.onNotificationPosted(sbn);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mNotificationLock) {
+ removeForegroundServiceFlagByListLocked(mEnqueuedNotifications, pkg, notificationId, userId);
+ removeForegroundServiceFlagByListLocked(mNotificationList, pkg, notificationId, userId);
}
- });
+ }
+ });
+ }
+
+ private void removeForegroundServiceFlagByListLocked(
+ ArrayList<NotificationRecord> notificationList, String pkg, int notificationId, int userId) {
+ NotificationRecord r =
+ findNotificationByListLocked(notificationList, pkg, null, notificationId, userId);
+ if (r == null) {
+ return;
}
+ StatusBarNotification sbn = r.sbn;
+ // NoMan adds flags FLAG_NO_CLEAR and FLAG_ONGOING_EVENT when it sees
+ // FLAG_FOREGROUND_SERVICE. Hence it's not enough to remove
+ // FLAG_FOREGROUND_SERVICE, we have to revert to the flags we received
+ // initially *and* force remove FLAG_FOREGROUND_SERVICE.
+ sbn.getNotification().flags =
+ (r.mOriginalFlags & ~Notification.FLAG_FOREGROUND_SERVICE);
+ mRankingHelper.sort(mNotificationList);
+ mListeners.notifyPostedLocked(sbn, sbn /* oldSbn */);
+ mGroupHelper.onNotificationPosted(sbn);
}
};
@@ -4663,8 +4665,11 @@
boolean hasCompanionDevice(ManagedServiceInfo info) {
if (mCompanionManager == null) {
- mCompanionManager = ICompanionDeviceManager.Stub.asInterface(
- ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE));
+ mCompanionManager = getCompanionManager();
+ }
+ // Companion mgr doesn't exist on all device types
+ if (mCompanionManager == null) {
+ return false;
}
long identity = Binder.clearCallingIdentity();
try {
@@ -4685,6 +4690,11 @@
return false;
}
+ protected ICompanionDeviceManager getCompanionManager() {
+ return ICompanionDeviceManager.Stub.asInterface(
+ ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE));
+ }
+
private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
if (!listener.enabledAndUserMatches(sbn.getUserId())) {
return false;
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/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 9e12f91..44dc61d 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -570,10 +570,6 @@
if (!r.showBadge) {
channel.setShowBadge(false);
}
- if (channel.getSound() == null) {
- channel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
- Notification.AUDIO_ATTRIBUTES_DEFAULT);
- }
r.channels.put(channel.getId(), channel);
MetricsLogger.action(getChannelLog(channel, pkg).setType(
MetricsProto.MetricsEvent.TYPE_OPEN));
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 66bb1cb..650d2f6 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -220,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;
@@ -1832,6 +1833,10 @@
extras.putInt(Intent.EXTRA_UID, res.uid);
if (update) {
extras.putBoolean(Intent.EXTRA_REPLACING, true);
+ } else {
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
+ extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
+ null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
extras, 0 /*flags*/, null /*targetPackage*/,
@@ -2722,15 +2727,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;
}
@@ -2751,6 +2759,7 @@
count++;
}
}
+ traceLog.traceEnd();
Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
}, "prepareAppData");
@@ -7090,17 +7099,23 @@
// used when either 1) the service is in an instant application and the
// caller is not the same instant application or 2) the calling package is
// ephemeral and the activity is not visible to ephemeral applications.
+ final boolean matchInstantApp =
+ (flags & PackageManager.MATCH_INSTANT) != 0;
final boolean matchVisibleToInstantAppOnly =
(flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
final boolean isCallerInstantApp =
instantAppPkgName != null;
final boolean isTargetSameInstantApp =
comp.getPackageName().equals(instantAppPkgName);
+ final boolean isTargetInstantApp =
+ (si.applicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
final boolean isTargetHiddenFromInstantApp =
(si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
final boolean blockResolution =
!isTargetSameInstantApp
- && ((matchVisibleToInstantAppOnly && isCallerInstantApp
+ && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
+ || (matchVisibleToInstantAppOnly && isCallerInstantApp
&& isTargetHiddenFromInstantApp));
if (!blockResolution) {
final ResolveInfo ri = new ResolveInfo();
@@ -7187,6 +7202,7 @@
Intent intent, String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
final int callingUid = Binder.getCallingUid();
+ final String instantAppPkgName = getInstantAppPackageName(callingUid);
flags = updateFlagsForResolve(flags, userId, intent, callingUid,
false /*includeInstantApps*/);
ComponentName comp = intent.getComponent();
@@ -7200,9 +7216,33 @@
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ProviderInfo pi = getProviderInfo(comp, flags, userId);
if (pi != null) {
- final ResolveInfo ri = new ResolveInfo();
- ri.providerInfo = pi;
- list.add(ri);
+ // When specifying an explicit component, we prevent the provider from being
+ // used when either 1) the provider is in an instant application and the
+ // caller is not the same instant application or 2) the calling package is an
+ // instant application and the provider is not visible to instant applications.
+ final boolean matchInstantApp =
+ (flags & PackageManager.MATCH_INSTANT) != 0;
+ final boolean matchVisibleToInstantAppOnly =
+ (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean isCallerInstantApp =
+ instantAppPkgName != null;
+ final boolean isTargetSameInstantApp =
+ comp.getPackageName().equals(instantAppPkgName);
+ final boolean isTargetInstantApp =
+ (pi.applicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
+ final boolean isTargetHiddenFromInstantApp =
+ (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
+ final boolean blockResolution =
+ !isTargetSameInstantApp
+ && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
+ || (matchVisibleToInstantAppOnly && isCallerInstantApp
+ && isTargetHiddenFromInstantApp));
+ if (!blockResolution) {
+ final ResolveInfo ri = new ResolveInfo();
+ ri.providerInfo = pi;
+ list.add(ri);
+ }
}
return list;
}
@@ -7211,17 +7251,67 @@
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
- return mProviders.queryIntent(intent, resolvedType, flags, userId);
+ return applyPostContentProviderResolutionFilter(
+ mProviders.queryIntent(intent, resolvedType, flags, userId),
+ instantAppPkgName);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
- return mProviders.queryIntentForPackage(
- intent, resolvedType, flags, pkg.providers, userId);
+ return applyPostContentProviderResolutionFilter(
+ mProviders.queryIntentForPackage(
+ intent, resolvedType, flags, pkg.providers, userId),
+ instantAppPkgName);
}
return Collections.emptyList();
}
}
+ private List<ResolveInfo> applyPostContentProviderResolutionFilter(
+ List<ResolveInfo> resolveInfos, String instantAppPkgName) {
+ // TODO: When adding on-demand split support for non-instant applications, remove
+ // this check and always apply post filtering
+ if (instantAppPkgName == null) {
+ return resolveInfos;
+ }
+ for (int i = resolveInfos.size() - 1; i >= 0; i--) {
+ final ResolveInfo info = resolveInfos.get(i);
+ final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
+ // allow providers that are defined in the provided package
+ if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
+ if (info.providerInfo.splitName != null
+ && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
+ info.providerInfo.splitName)) {
+ // requested provider is defined in a split that hasn't been installed yet.
+ // add the installer to the resolve list
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
+ }
+ final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
+ installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
+ info.providerInfo.packageName, info.providerInfo.splitName,
+ info.providerInfo.applicationInfo.versionCode);
+ // make sure this resolver is the default
+ installerInfo.isDefault = true;
+ installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
+ | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
+ // add a non-generic filter
+ installerInfo.filter = new IntentFilter();
+ // load resources from the correct package
+ installerInfo.resolvePackageName = info.getComponentInfo().packageName;
+ resolveInfos.set(i, installerInfo);
+ }
+ continue;
+ }
+ // allow providers that have been explicitly exposed to instant applications
+ if (!isEphemeralApp
+ && ((info.providerInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
+ continue;
+ }
+ resolveInfos.remove(i);
+ }
+ return resolveInfos;
+ }
+
@Override
public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
@@ -7553,17 +7643,38 @@
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId, name);
+ final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
// reader
synchronized (mPackages) {
final PackageParser.Provider provider = mProvidersByAuthority.get(name);
PackageSetting ps = provider != null
? mSettings.mPackages.get(provider.owner.packageName)
: null;
- return ps != null
- && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
- ? PackageParser.generateProviderInfo(provider, flags,
- ps.readUserState(userId), userId)
- : null;
+ if (ps != null) {
+ final boolean isInstantApp = ps.getInstantApp(userId);
+ // normal application; filter out instant application provider
+ if (instantAppPkgName == null && isInstantApp) {
+ return null;
+ }
+ // instant application; filter out other instant applications
+ if (instantAppPkgName != null
+ && isInstantApp
+ && !provider.owner.packageName.equals(instantAppPkgName)) {
+ return null;
+ }
+ // instant application; filter out non-exposed provider
+ if (instantAppPkgName != null
+ && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0) {
+ return null;
+ }
+ // provider not enabled
+ if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
+ return null;
+ }
+ return PackageParser.generateProviderInfo(
+ provider, flags, ps.readUserState(userId), userId);
+ }
+ return null;
}
}
@@ -12767,8 +12878,26 @@
if (ps == null) {
return null;
}
+ final PackageUserState userState = ps.readUserState(userId);
+ final boolean matchVisibleToInstantApp =
+ (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ // throw out filters that aren't visible to instant applications
+ if (matchVisibleToInstantApp
+ && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+ return null;
+ }
+ // throw out instant application filters if we're not explicitly requesting them
+ if (!isInstantApp && userState.instantApp) {
+ return null;
+ }
+ // throw out instant application filters if updates are available; will trigger
+ // instant application resolution
+ if (userState.instantApp && ps.isUpdateAvailable()) {
+ return null;
+ }
ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
- ps.readUserState(userId), userId);
+ userState, userId);
if (pi == null) {
return null;
}
@@ -13266,8 +13395,10 @@
// Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
- sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
- packageName, extras, 0, null, null, userIds);
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
+ extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, userIds);
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+ extras, 0, null, null, userIds);
if (isSystem) {
mHandler.post(() -> {
for (int userId : userIds) {
@@ -23350,7 +23481,6 @@
intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
}
-
@Override
public void addIsolatedUid(int isolatedUid, int ownerUid) {
synchronized (mPackages) {
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/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 0b90bad..bde2111 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -715,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 f4f6b63..1fb34eb 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1550,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/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/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index e285669..d383aea 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -215,6 +215,8 @@
builder.setSound(CUSTOM_SOUND);
channel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
}
+ } else {
+ channel.setSound(null, null);
}
if (buzzy) {
if (defaultVibration) {
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
index 176342b..84945ab 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
@@ -75,6 +75,7 @@
private NotificationRecord mRecordContact;
private NotificationRecord mRecordUrgent;
private NotificationRecord mRecordCheater;
+ private NotificationRecord mRecordCheaterColorized;
@Before
@@ -174,6 +175,7 @@
pkg2, 1, "cheater", uid2, uid2, n9, new UserHandle(userId),
"", 9258), getDefaultChannel());
mRecordCheater.setUserImportance(NotificationManager.IMPORTANCE_LOW);
+ mRecordCheater.setPackagePriority(Notification.PRIORITY_MAX);
Notification n10 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
.setStyle(new Notification.InboxStyle().setSummaryText("message!")).build();
@@ -181,6 +183,15 @@
pkg2, 1, "email", uid2, uid2, n10, new UserHandle(userId),
"", 1599), getDefaultChannel());
mRecordEmail.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
+
+ Notification n11 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
+ .setCategory(Notification.CATEGORY_MESSAGE)
+ .setColorized(true)
+ .build();
+ mRecordCheaterColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
+ pkg2, 1, "cheater", uid2, uid2, n11, new UserHandle(userId),
+ "", 9258), getDefaultChannel());
+ mRecordCheaterColorized.setUserImportance(NotificationManager.IMPORTANCE_LOW);
}
@Test
@@ -195,6 +206,7 @@
expected.add(mRecordEmail);
expected.add(mRecordUrgent);
expected.add(mRecordCheater);
+ expected.add(mRecordCheaterColorized);
expected.add(mRecordMinCall);
List<NotificationRecord> actual = new ArrayList<>();
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 07e4bb8..f666727 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -19,6 +19,7 @@
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@@ -99,6 +100,11 @@
protected boolean isCallerSystem() {
return true;
}
+
+ @Override
+ protected ICompanionDeviceManager getCompanionManager() {
+ return null;
+ }
}
@Before
@@ -644,4 +650,13 @@
new IllegalArgumentException());
mNotificationManagerService.hasCompanionDevice(mListener);
}
+
+ @Test
+ @UiThreadTest
+ public void testHasCompanionDevice_noService() throws Exception {
+ mNotificationManagerService = new TestableNotificationManagerService(mContext);
+
+ assertFalse(mNotificationManagerService.hasCompanionDevice(mListener));
+ }
+
}
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index 885eb2e..303054e 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -738,15 +738,6 @@
}
@Test
- public void testCreateChannel_addMissingSound() throws Exception {
- final NotificationChannel channel =
- new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG, UID, channel, true);
- assertNotNull(mHelper.getNotificationChannel(
- PKG, UID, channel.getId(), false).getSound());
- }
-
- @Test
public void testCreateChannel_noOverrideSound() throws Exception {
Uri sound = new Uri.Builder().scheme("test").build();
final NotificationChannel channel = new NotificationChannel("id2", "name2",
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 353199a..985e5ea 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -23,7 +23,6 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@@ -37,7 +36,7 @@
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -49,7 +48,6 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.INetworkRecommendationProvider;
@@ -94,8 +92,6 @@
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -138,11 +134,13 @@
@Mock private Context mContext;
@Mock private Resources mResources;
@Mock private INetworkScoreCache.Stub mNetworkScoreCache, mNetworkScoreCache2;
- @Mock private IBinder mIBinder, mIBinder2;
+ @Mock private IBinder mScoreCacheIBinder, mScoreCacheIBinder2;
+ @Mock private IBinder mServiceConnectionIBinder;
@Mock private INetworkRecommendationProvider mRecommendationProvider;
@Mock private UnaryOperator<List<ScoredNetwork>> mCurrentNetworkFilter;
@Mock private UnaryOperator<List<ScoredNetwork>> mScanResultsFilter;
@Mock private WifiInfo mWifiInfo;
+ @Mock private NetworkScoreService.ScoringServiceConnection mServiceConnection;
@Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
private ContentResolver mContentResolver;
@@ -160,17 +158,22 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- when(mNetworkScoreCache.asBinder()).thenReturn(mIBinder);
- when(mNetworkScoreCache2.asBinder()).thenReturn(mIBinder2);
+ when(mNetworkScoreCache.asBinder()).thenReturn(mScoreCacheIBinder);
+ when(mNetworkScoreCache2.asBinder()).thenReturn(mScoreCacheIBinder2);
+ when(mServiceConnectionIBinder.queryLocalInterface(anyString()))
+ .thenReturn(mRecommendationProvider);
mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getResources()).thenReturn(mResources);
when(mWifiInfo.getSSID()).thenReturn(SCORED_NETWORK.networkKey.wifiKey.ssid);
when(mWifiInfo.getBSSID()).thenReturn(SCORED_NETWORK.networkKey.wifiKey.bssid);
+ when(mServiceConnection.getAppData()).thenReturn(NEW_SCORER);
+ when(mServiceConnection.getRecommendationProvider()).thenReturn(mRecommendationProvider);
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
mHandlerThread.start();
mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager,
- mHandlerThread.getLooper());
+ networkScorerAppData -> mServiceConnection, mHandlerThread.getLooper());
WifiConfiguration configuration = new WifiConfiguration();
configuration.SSID = "NetworkScoreServiceTest_SSID";
configuration.BSSID = "NetworkScoreServiceTest_BSSID";
@@ -209,12 +212,10 @@
mNetworkScoreService.onUserUnlocked(0);
- verify(mContext).bindServiceAsUser(MockUtils.checkIntent(
- new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
- .setComponent(RECOMMENDATION_SERVICE_COMP)),
- any(ServiceConnection.class),
- eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
- eq(UserHandle.SYSTEM));
+ verify(mNetworkScorerAppManager).updateState();
+ verify(mNetworkScorerAppManager).migrateNetworkScorerAppSettingIfNeeded();
+ verify(mServiceConnection).bind(mContext);
+
}
@Test
@@ -238,16 +239,16 @@
@Test
public void testRequestScores_providerThrowsRemoteException() throws Exception {
- injectProvider();
doThrow(new RemoteException()).when(mRecommendationProvider)
.requestScores(any(NetworkKey[].class));
+ mNetworkScoreService.onUserUnlocked(0);
assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0]));
}
@Test
public void testRequestScores_providerAvailable() throws Exception {
- injectProvider();
+ mNetworkScoreService.onUserUnlocked(0);
final NetworkKey[] networks = new NetworkKey[0];
assertTrue(mNetworkScoreService.requestScores(networks));
@@ -291,11 +292,11 @@
@Test
public void testRequestRecommendation_providerThrowsRemoteException() throws Exception {
- injectProvider();
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
doThrow(new RemoteException()).when(mRecommendationProvider)
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
anyInt());
+ mNetworkScoreService.onUserUnlocked(0);
final RecommendationResult result =
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
@@ -306,7 +307,6 @@
@Test
public void testRequestRecommendation_resultReturned() throws Exception {
- injectProvider();
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
final WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = "testRequestRecommendation_resultReturned_SSID";
@@ -322,6 +322,7 @@
}).when(mRecommendationProvider)
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
anyInt());
+ mNetworkScoreService.onUserUnlocked(0);
final RecommendationResult result =
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
@@ -357,7 +358,7 @@
@Test
public void testRequestRecommendationAsync_requestTimesOut() throws Exception {
- injectProvider();
+ mNetworkScoreService.onUserUnlocked(0);
Settings.Global.putLong(mContentResolver,
Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, 1L);
mNetworkScoreService.refreshRecommendationRequestTimeoutMs();
@@ -378,7 +379,7 @@
@Test
public void testRequestRecommendationAsync_requestSucceeds() throws Exception {
- injectProvider();
+ mNetworkScoreService.onUserUnlocked(0);
final Bundle bundle = new Bundle();
doAnswer(invocation -> {
invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
@@ -397,7 +398,7 @@
@Test
public void testRequestRecommendationAsync_requestThrowsRemoteException() throws Exception {
- injectProvider();
+ mNetworkScoreService.onUserUnlocked(0);
doThrow(new RemoteException()).when(mRecommendationProvider)
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
anyInt());
@@ -657,9 +658,13 @@
@Test
public void testIsCallerActiveScorer_noBoundService() throws Exception {
+ // No active scorer.
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(null);
mNetworkScoreService.onUserUnlocked(0);
- assertFalse(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid()));
+ mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid());
+
+ verify(mServiceConnection, never()).getAppData();
}
@Test
@@ -678,9 +683,13 @@
@Test
public void testGetActiveScorerPackage_notActive() throws Exception {
+ // No active scorer.
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(null);
mNetworkScoreService.onUserUnlocked(0);
- assertNull(mNetworkScoreService.getActiveScorerPackage());
+ mNetworkScoreService.getActiveScorerPackage();
+
+ verify(mServiceConnection, never()).getPackageName();
}
@Test
@@ -688,10 +697,9 @@
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
mNetworkScoreService.onUserUnlocked(0);
- assertEquals(NEW_SCORER.getRecommendationServicePackageName(),
- mNetworkScoreService.getActiveScorerPackage());
- assertEquals(NEW_SCORER.getEnableUseOpenWifiActivity(),
- mNetworkScoreService.getActiveScorer().getEnableUseOpenWifiActivity());
+ mNetworkScoreService.getActiveScorerPackage();
+
+ verify(mServiceConnection).getPackageName();
}
@Test
@@ -931,7 +939,12 @@
public void testGetActiveScorer_notConnected_canRequestScores() throws Exception {
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
.thenReturn(PackageManager.PERMISSION_GRANTED);
- assertNull(mNetworkScoreService.getActiveScorer());
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(null);
+ mNetworkScoreService.onUserUnlocked(0);
+
+ mNetworkScoreService.getActiveScorer();
+
+ verify(mServiceConnection, never()).getAppData();
}
@Test
@@ -951,11 +964,11 @@
throws Exception {
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
.thenReturn(PackageManager.PERMISSION_GRANTED);
- NetworkScorerAppData expectedAppData = new NetworkScorerAppData(Binder.getCallingUid(),
- RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
- USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID);
- bindToScorer(expectedAppData);
- assertEquals(expectedAppData, mNetworkScoreService.getActiveScorer());
+ mNetworkScoreService.onUserUnlocked(0);
+
+ mNetworkScoreService.getActiveScorer();
+
+ verify(mServiceConnection).getAppData();
}
@Test
@@ -972,23 +985,98 @@
}
}
- // "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
- private void injectProvider() {
- when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
- when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
- isA(UserHandle.class))).thenAnswer(new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- IBinder mockBinder = mock(IBinder.class);
- when(mockBinder.queryLocalInterface(anyString()))
- .thenReturn(mRecommendationProvider);
- invocation.<ServiceConnection>getArgument(1)
- .onServiceConnected(NEW_SCORER.getRecommendationServiceComponent(),
- mockBinder);
- return true;
- }
- });
- mNetworkScoreService.onUserUnlocked(0);
+ @Test
+ public void testServiceConnection_bind_notBound() throws Exception {
+ NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService
+ .ScoringServiceConnection(NEW_SCORER);
+ connection.bind(mContext);
+
+ verify(mContext).bindServiceAsUser(MockUtils.checkIntent(
+ new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
+ .setComponent(RECOMMENDATION_SERVICE_COMP)),
+ eq(connection),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM));
+ }
+
+ @Test
+ public void testServiceConnection_bind_alreadyBound() throws Exception {
+ NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService
+ .ScoringServiceConnection(NEW_SCORER);
+
+ when(mContext.bindServiceAsUser(MockUtils.checkIntent(
+ new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
+ .setComponent(RECOMMENDATION_SERVICE_COMP)),
+ eq(connection),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM))).thenReturn(true /*bound*/);
+
+ // Calling bind more than once should only result in 1 bindService call.
+ connection.bind(mContext);
+ connection.bind(mContext);
+
+ verify(mContext, times(1)).bindServiceAsUser(MockUtils.checkIntent(
+ new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
+ .setComponent(RECOMMENDATION_SERVICE_COMP)),
+ eq(connection),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM));
+ }
+
+ @Test
+ public void testServiceConnection_bindFails() throws Exception {
+ NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService
+ .ScoringServiceConnection(NEW_SCORER);
+
+ when(mContext.bindServiceAsUser(MockUtils.checkIntent(
+ new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
+ .setComponent(RECOMMENDATION_SERVICE_COMP)),
+ eq(connection),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM))).thenReturn(false /*bound*/);
+
+ connection.bind(mContext);
+
+ verify(mContext).unbindService(connection);
+ }
+
+ @Test
+ public void testServiceConnection_unbind_notBound() throws Exception {
+ NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService
+ .ScoringServiceConnection(NEW_SCORER);
+
+ connection.unbind(mContext);
+
+ verify(mContext, never()).unbindService(connection);
+ }
+
+ @Test
+ public void testServiceConnection_unbind_alreadyBound() throws Exception {
+ NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService
+ .ScoringServiceConnection(NEW_SCORER);
+
+ when(mContext.bindServiceAsUser(MockUtils.checkIntent(
+ new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
+ .setComponent(RECOMMENDATION_SERVICE_COMP)),
+ eq(connection),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM))).thenReturn(true /*bound*/);
+
+ connection.bind(mContext);
+ connection.unbind(mContext);
+
+ verify(mContext).unbindService(connection);
+ }
+
+ @Test
+ public void testServiceConnection_dump_doesNotCrash() throws Exception {
+ NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService
+ .ScoringServiceConnection(NEW_SCORER);
+ final StringWriter stringWriter = new StringWriter();
+
+ connection.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
+
+ assertFalse(stringWriter.toString().isEmpty());
}
private void bindToScorer(boolean callerIsScorer) {
@@ -996,13 +1084,7 @@
NetworkScorerAppData appData = new NetworkScorerAppData(callingUid,
RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID);
- bindToScorer(appData);
- }
-
- private void bindToScorer(NetworkScorerAppData appData) {
- when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData);
- when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
- isA(UserHandle.class))).thenReturn(true);
+ when(mServiceConnection.getAppData()).thenReturn(appData);
mNetworkScoreService.onUserUnlocked(0);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 9861aa1..cd39d88 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -708,7 +708,7 @@
Drawable dr = mLauncherApps.getShortcutIconDrawable(
makeShortcutWithIcon("bmp64x64", bmp64x64_maskable), 0);
assertTrue(dr instanceof AdaptiveIconDrawable);
- float viewportPercentage = 1 / (1 + 2 * AdaptiveIconDrawable.getExtraInsetPercentage());
+ float viewportPercentage = 1 / (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction());
assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
dr.getIntrinsicWidth());
assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index dc4b41c..6c4ced4 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -302,9 +302,13 @@
ComponentName curInteractor = !TextUtils.isEmpty(curInteractorStr)
? ComponentName.unflattenFromString(curInteractorStr) : null;
try {
- recognizerInfo = pm.getServiceInfo(curRecognizer, 0, userHandle);
+ recognizerInfo = pm.getServiceInfo(curRecognizer,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle);
if (curInteractor != null) {
- interactorInfo = pm.getServiceInfo(curInteractor, 0, userHandle);
+ interactorInfo = pm.getServiceInfo(curInteractor,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle);
}
} catch (RemoteException e) {
}
@@ -492,7 +496,9 @@
ComponentName findAvailRecognizer(String prefPackage, int userHandle) {
List<ResolveInfo> available =
mContext.getPackageManager().queryIntentServicesAsUser(
- new Intent(RecognitionService.SERVICE_INTERFACE), 0, userHandle);
+ new Intent(RecognitionService.SERVICE_INTERFACE),
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle);
int numAvailable = available.size();
if (numAvailable == 0) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 77da897..d60f25c 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) {
}
@@ -6458,5 +6478,33 @@
return null;
}
+
+ /**
+ * Check if phone is in emergency callback mode
+ * @return true if phone is in emergency callback mode
+ * @hide
+ */
+ public boolean getEmergencyCallbackMode() {
+ return getEmergencyCallbackMode(getSubId());
+ }
+
+ /**
+ * Check if phone is in emergency callback mode
+ * @return true if phone is in emergency callback mode
+ * @param subId the subscription ID that this action applies to.
+ * @hide
+ */
+ public boolean getEmergencyCallbackMode(int subId) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) {
+ return false;
+ }
+ return telephony.getEmergencyCallbackMode(subId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#getEmergencyCallbackMode", e);
+ }
+ return false;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index db7e417..b461a78 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.
@@ -1315,4 +1316,12 @@
* @param appType the icc application type, like {@link #APPTYPE_USIM}
*/
String[] getForbiddenPlmns(int subId, int appType);
+
+ /**
+ * Check if phone is in emergency callback mode
+ * @return true if phone is in emergency callback mode
+ * @param subId the subscription ID that this action applies to.
+ * @hide
+ */
+ boolean getEmergencyCallbackMode(int subId);
}
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_;